KarolGil's avatar

routing in laravel 6 - MethodNotAllowedHttpException

Laravel 6

app/Http/Middleware/Authenticate.php

    public function handle($request, Closure $next, ...$guards)
    {
        if(in_array('auth:api',$request->route()->action['middleware'])){
            $request->headers->set('authorization',['Bearer '.$request->post('accessToken')]);
        }
        $this->authenticate($request, $guards);
        return $next($request);
    }

app/Exceptions/Handler.php

   protected function unauthenticated($request, AuthenticationException $exception)
    {
         if(in_array('auth:api',$request->route()->action['middleware']))
         {
            return response()->json(['message' => 'Unauthenticated.'], 401);
         }

        return redirect()->guest(route('login'));
    }

routes/api.php

Route::post('login', 'ApiLoginController@login')->name('login');

Route::middleware('auth:api')->group(function () {
    Route::post('/testMethod', 'ApiController@testMethod');
});

app/Http/Controllers/ApiController.php

public function testMethod(Request $request)
{
      dd('test');
}

. . . . .

Why should I have a GET request?

Route::get('/testMethod', 'ApiController@testMethod');

it all works for me.

However, when it changes to POST

Route::post('/testMethod', 'ApiController@testMethod');

This is my mistake in Postman:

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: The POST method is not supported for this route. Supported methods: GET, HEAD. in file /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php on line 256

#0 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(242): Illuminate\Routing\RouteCollection->methodNotAllowed(Array, 'POST')
#1 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(176): Illuminate\Routing\RouteCollection->getRouteForMethods(Object(Illuminate\Http\Request), Array)
#2 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(635): Illuminate\Routing\RouteCollection->match(Object(Illuminate\Http\Request))
#3 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(624): Illuminate\Routing\Router->findRoute(Object(Illuminate\Http\Request))
#4 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(613): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#5 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(177): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#6 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#7 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#8 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#9 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#10 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#11 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#12 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
#13 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#14 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#15 /var/www/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#16 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Fideloper\Proxy\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
#17 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#18 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(152): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#19 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(117): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#20 /var/www/public/index.php(55): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#21 {main}
0 likes
15 replies
Alkut's avatar

Try this command ‘php artisan cache:clear’

Nakov's avatar

@karolgil are you maybe using php artisan serve ? Try killing the server and starting it again whenever you change something..

Run php artisan route:list and make sure that you have POST route for that endpoint.

KarolGil's avatar
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+
| Domain | Method   | URI                                     | Name                              | Action                                                                    |
Middleware   |
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+
|        | GET|HEAD | /                                       |                                   | Closure                                                                   |
api,auth:api |
|        | POST     | api/login                               | login                             | App\Http\Controllers\ApiLoginController@login                             |
api          |
|        | GET|HEAD | api/testMethod                          |                                   | App\Http\Controllers\ApiController@testMethod                             |
api,auth:api |
|        | GET|HEAD | oauth/authorize                         | passport.authorizations.authorize | Laravel\Passport\Http\Controllers\AuthorizationController@authorize       |
web,auth     |
|        | DELETE   | oauth/authorize                         | passport.authorizations.deny      | Laravel\Passport\Http\Controllers\DenyAuthorizationController@deny        |
web,auth     |
|        | POST     | oauth/authorize                         | passport.authorizations.approve   | Laravel\Passport\Http\Controllers\ApproveAuthorizationController@approve  |
web,auth     |
|        | GET|HEAD | oauth/clients                           | passport.clients.index            | Laravel\Passport\Http\Controllers\ClientController@forUser                |
web,auth     |
|        | POST     | oauth/clients                           | passport.clients.store            | Laravel\Passport\Http\Controllers\ClientController@store                  |
web,auth     |
|        | PUT      | oauth/clients/{client_id}               | passport.clients.update           | Laravel\Passport\Http\Controllers\ClientController@update                 |
web,auth     |
|        | DELETE   | oauth/clients/{client_id}               | passport.clients.destroy          | Laravel\Passport\Http\Controllers\ClientController@destroy                |
web,auth     |
|        | GET|HEAD | oauth/personal-access-tokens            | passport.personal.tokens.index    | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser   |
web,auth     |
|        | POST     | oauth/personal-access-tokens            | passport.personal.tokens.store    | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store     |
web,auth     |
|        | DELETE   | oauth/personal-access-tokens/{token_id} | passport.personal.tokens.destroy  | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy   |
web,auth     |
|        | GET|HEAD | oauth/scopes                            | passport.scopes.index             | Laravel\Passport\Http\Controllers\ScopeController@all                     |
web,auth     |
|        | POST     | oauth/token                             | passport.token                    | Laravel\Passport\Http\Controllers\AccessTokenController@issueToken        |
throttle     |
|        | POST     | oauth/token/refresh                     | passport.token.refresh            | Laravel\Passport\Http\Controllers\TransientTokenController@refresh        |
web,auth     |
|        | GET|HEAD | oauth/tokens                            | passport.tokens.index             | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser |
web,auth     |
|        | DELETE   | oauth/tokens/{token_id}                 | passport.tokens.destroy           | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy |
web,auth     |
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+

Still the same error.

Nakov's avatar

@karolgil of course the same error, take a look at your list:

You've got this:

|        | GET|HEAD | api/testMethod                          |                                   | App\Http\Controllers\ApiController@testMethod                             |

It is a GET method, not a POST. So that route is not even registered.

KarolGil's avatar
|        | POST     | api/testMethod                          |                                   | App\Http\Controllers\ApiController@testMethod                             |
api,auth:api |

I have changed to post and the same error remains.

Where can the error be located?

Nakov's avatar

@karolgil you've changed it here, or you've changed it in your routes, and you shared the result from a php artisan route:list because if you have a POST route for that endpoint, then the error should be gone.

Change the endpoint to something else and try again then.

KarolGil's avatar
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+
| Domain | Method   | URI                                     | Name                              | Action                                                                    |
Middleware   |
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+
|        | GET|HEAD | /                                       |                                   | Closure                                                                   |
web          |
|        | POST     | api/login                               | login                             | App\Http\Controllers\ApiLoginController@login                             |
api          |
|        | GET|HEAD | api/testMethod                          |                                   | App\Http\Controllers\ApiController@testMethod                             |
api,auth:api |
|        | POST     | api/testMethod                          |                                   | App\Http\Controllers\ApiController@testMethod                             |
api,auth:api |
|        | POST     | oauth/authorize                         | passport.authorizations.approve   | Laravel\Passport\Http\Controllers\ApproveAuthorizationController@approve  |
web,auth     |
|        | GET|HEAD | oauth/authorize                         | passport.authorizations.authorize | Laravel\Passport\Http\Controllers\AuthorizationController@authorize       |
web,auth     |
|        | DELETE   | oauth/authorize                         | passport.authorizations.deny      | Laravel\Passport\Http\Controllers\DenyAuthorizationController@deny        |
web,auth     |
|        | GET|HEAD | oauth/clients                           | passport.clients.index            | Laravel\Passport\Http\Controllers\ClientController@forUser                |
web,auth     |
|        | POST     | oauth/clients                           | passport.clients.store            | Laravel\Passport\Http\Controllers\ClientController@store                  |
web,auth     |
|        | PUT      | oauth/clients/{client_id}               | passport.clients.update           | Laravel\Passport\Http\Controllers\ClientController@update                 |
web,auth     |
|        | DELETE   | oauth/clients/{client_id}               | passport.clients.destroy          | Laravel\Passport\Http\Controllers\ClientController@destroy                |
web,auth     |
|        | GET|HEAD | oauth/personal-access-tokens            | passport.personal.tokens.index    | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser   |
web,auth     |
|        | POST     | oauth/personal-access-tokens            | passport.personal.tokens.store    | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store     |
web,auth     |
|        | DELETE   | oauth/personal-access-tokens/{token_id} | passport.personal.tokens.destroy  | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy   |
web,auth     |
|        | GET|HEAD | oauth/scopes                            | passport.scopes.index             | Laravel\Passport\Http\Controllers\ScopeController@all                     |
web,auth     |
|        | POST     | oauth/token                             | passport.token                    | Laravel\Passport\Http\Controllers\AccessTokenController@issueToken        |
throttle     |
|        | POST     | oauth/token/refresh                     | passport.token.refresh            | Laravel\Passport\Http\Controllers\TransientTokenController@refresh        |
web,auth     |
|        | GET|HEAD | oauth/tokens                            | passport.tokens.index             | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser |
web,auth     |
|        | DELETE   | oauth/tokens/{token_id}                 | passport.tokens.destroy           | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy |
web,auth     |
+--------+----------+-----------------------------------------+-----------------------------------+---------------------------------------------------------------------------+-
-------------+

I've even set up two routes, one for post and one for get. And it works for get and not for post.

Nakov's avatar

@karolgil but is the error still the same or you are getting something new now? It should not be the same error now I believe.

Make sure you are posting to /api/testMethod.

KarolGil's avatar

I have the same mistake all the time. Although it also makes no sense to me.

Can this error have something to do with Passport or csrt_token?

Nakov's avatar

@karolgil you can test that by moving them out of the api:auth group. And see if it works. If they are registered in api.php then csrf_token is not applicable there, but the Passport is for sure. Now if that's the case you should be getting a different error, and not that the POST method is not accepted for the testMethod route.

KarolGil's avatar

routes/api.php

Route::middleware([])->group(function () {
    Route::post('/testMethod', 'ApiController@testMethod');
    Route::get('/testMethod', 'ApiController@testMethod');
});

If I remove auth:api then the post request works. So where should I look for a mistake?

Nakov's avatar

@karolgil and what if you add them in the other order:

Route::middleware('auth:api')->group(function () {
    Route::get('/testMethod', 'ApiController@testMethod');
    Route::post('/testMethod', 'ApiController@testMethod');
});

Will this now work?

If it does not then look for the mistake in the files that you edited manually.. Like the middleware.

KarolGil's avatar

How to check where there may be an error in auth:api? Because if I remove auth: api, the post request works.

KarolGil's avatar
KarolGil
OP
Best Answer
Level 9

The problem was that the file was app/Http/Middleware/Authenticate.php

$request->headers->set('authorization',['Bearer '.$request->post('accessToken')]);

and it should be

$request->headers->set('authorization',['Bearer '.$request->input('accessToken')]);

the app/Http/Middleware/Authenticate.php file should look like this:

public function handle($request, Closure $next, ...$guards)
{
    if(in_array('auth:api', $request->route()->action['middleware'])) {
        $request->headers->set('authorization',['Bearer '.$request->input('accessToken')]);
    }

    $this->authenticate($request, $guards);
    return $next($request);
}

Thank you all for your help.

Please or to participate in this conversation.