paveLeb's avatar

This action is unauthorized API

I am writing a couple of API endpoints and I am having an issue with the following route.

Route:

Route::put('clients/{id}', 'ClientController@updateSettingsClient');

it throws an This action is unauthorized. error whenever I run the request. ClientController has the required function.

It works whenever I use the build in names, Route::resource( 'clients', 'ClientController', ['only' => ['index', 'store', 'show', 'update', 'destroy']] ); but I will have more than one update function so I can't name them both update.

Any idea why it might be happening?

0 likes
17 replies
tykus's avatar

What does the other update (PUT) route URI look like?

1 like
paveLeb's avatar

@tykus there isn't one. It is only Route::put('clients/{id}', 'ClientController@updateSettingsClient'); in the routes/api.php file

tykus's avatar

Oh, right.

In that case, is there a FormRequest type-hinted on the updateSettingsClient controller method? And does that Request class return true (or truthy) from the authorize() method?

Or, is the route defined inside a group that uses the auth middleware? And, are you making the request as an authenticated user?

2 likes
tykus's avatar

What is the updateSettingsClient method signature?

1 like
paveLeb's avatar

@tykus

public function updateSettingsClient(Client $client, ApiClientRequest $request, ClientRepository $clientRepo, ClientTransformer $transformer)`

Within ApiClientRequest it is set up to true

public function authorize()
    {   
        return true;
    }   

The routes file looks like this:

Route::group(["middleware" => ['api','lang'], "namespace" => 'Api'], function() {
    Route::prefix('v1')->group(function () {
    // THIS ONE WORKS IF I NAME THE METHOD update
    Route::resource( 'clients', 'ClientController', ['only' => ['index', 'store', 'show', 'update', 'destroy']] );
    // THIS ONE GIVES THE ERROR
    Route::put('clients/{id}', 'ClientController@updateSettingsClient');
    }); 
});
1 like
Cronix's avatar
Route::resource( 'clients', 'ClientController', ['only' => ['index', 'store', 'show', 'update', 'destroy']] );
// THIS ONE GIVES THE ERROR
Route::put('clients/{id}', 'ClientController@updateSettingsClient');

I think you need to switch the order of those 2 routes. But, why wouldn't you just use the traditional update method in the resource controller?

1 like
tykus's avatar

What does the other update (PUT) route URI look like?

I asked this earlier... you do have a second PUT route, owing to your resource route definition; and it is being matched first, so your updateSettingsClient method is never hit.

1 like
paveLeb's avatar

@Cronix The resource one isn't running. I just put it there to show the one that gives no error if I call the method update and not updateSettingsClient.

I need to have two update methods because I have two different things under the Settings functionality that need to be updated.

paveLeb's avatar

@tykus I forgot to comment the actual line in the post. It is commented out in the code.

Route::group(["middleware" => ['api','lang'], "namespace" => 'Api'], function() {
    Route::prefix('v1')->group(function () {
        // Route::resource( 'clients', 'ClientController', ['only' => ['index', 'store', 'show', 'update', 'destroy']] );
        // THIS ONE GIVES THE ERROR
        Route::put('clients/{id}', 'ClientController@updateSettingsClient');
    }); 
});
tykus's avatar

You are going to have a problem with the two PUT routes having the same method signature.

What is the api middleware; is that the api group? You get that automatically in the routes/api.php file whenever it is mapped; you do not need to explicitly group your routes with that middleware.

1 like
Cronix's avatar

You still need to change the order since they are going to the same controller. The resource route should be last.

1 like
paveLeb's avatar

@tykus I will have a problem even if the other method has a different name?

The other method is updateProfileClient so I was thinking about having something like this:

Route::put('clients/{id}', 'ClientController@updateSettingsClient');
Route::put('clients/{id}', 'ClientController@updateProfileClient');

That won't work though?

Cronix's avatar

The problem is this part Route::put('clients/{id}'. They are the same url using the same http verb PUT. The urls need to be different (clients/{id}). Otherwise it will use whichever route is listed first when going to /clients/id using PUT

1 like
tykus's avatar

I will have a problem even if the other method has a different name?

You absolutely will, yes. Laravel will match the first route it finds, never the second.

1 like
ramphy's avatar

I solve using a middleware guest

Route::post('/cartx', [CartXController::class, 'cartx'])->middleware('guest'); ​

Please or to participate in this conversation.