Search code examples
laravellaravel-passportlaravel-7scopes

Applying Passport scopes conditionally on api resource methods


I am using passport personal access token to secure my API. Here are some of the code snippets.

// api.php
Route::apiResource('categories', 'CategoryController');

AuthServiceProvider.php

public function boot()
    {
        $this->registerPolicies();

        //scopes 
        Passport::tokensCan([
            'admin' => 'Perform every action',
            'user' => 'Perform only normal user actions',
        ]);

        // passport routes
        Passport::routes();
        //
    }

CategoryController.php

class CategoryController extends Controller
{
    function __construct()
    {
        $this->middleware('api:auth', ['scopes: admin']);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {   
        return CategoryResource::collection(Category::all()); 
    }
    ...

As you can see I have used the admin scope which is only accessible to admin users. But the problem is category model can only be edited or updated by the admin scope and can be accessed by both admin and user scopes. What could be the best approach to address this issue?


Solution

  • One solution that worked for me is I have used middleware two times with different scopes.

    class CategoryController extends Controller
    {
        function __construct()
        {
            $this->middleware('api:auth', ['scopes: admin'])->except(['index']);
            $this->middleware('api:auth', ['scopes: user'])->only(['index']);
        }
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index(Request $request)
        {   
            return CategoryResource::collection(Category::all()); 
        }
        ...