Search code examples
laravellaravel-jetstream

How to use laravel's can() on routes when using JetStream


I'm trying to work out how to use ->can() on a route when combined with JetStream's permissions.

I can see how to create permissions in the JetStreamServiceProvider.php:


 protected function configurePermissions()
    {
        Jetstream::defaultApiTokenPermissions(['read']);

        Jetstream::role('admin', __('Administrator'), [
            'export:orders'
        ])->description(__('Administrator users can perform any action.'));

However I can work out how to combine this with a route:

Route::get('/generate-export/orders', [OrderExportController::class,'show'])->name('exportOrders.show')->can(' -- not sure what to put here --');

I've tried a few things and got nowhere.


Solution

  • Those tokens are used for requests authenticated with sanctum. As their documentation states in:

    Sanctum 9.x - Token Ability Middleware

    Yoiu need to first add 2 entries to the route middleware array in your App\Http\Kernel.php file.

    protected $routeMiddleware = [
        ...,
        'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
        'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
    ];
    

    And then, you can use those middlewares in your routes.

    Route::get('/generate-export/orders', [OrderExportController::class,'show'])
        ->name('exportOrders.show')
        ->middleware(['auth:sanctum', 'ability:export:orders']); // check if user has export:orders ability
    

    As for the difference between abilities and ability, to quote the documentation:

    The abilities middleware may be assigned to a route to verify that the incoming request's token has all of the listed abilities:

    Route::get('/orders', function () {
        // Token has both "check-status" and "place-orders" abilities...
    })->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);
    

    The ability middleware may be assigned to a route to verify that the incoming request's token has at least one of the listed abilities:

    Route::get('/orders', function () {
        // Token has the "check-status" or "place-orders" ability...
    })->middleware(['auth:sanctum', 'ability:check-status,place-orders']);