Laravel Passport Scopes

后端 未结 6 1028
灰色年华
灰色年华 2020-11-28 21:10

I am a bit confused on the laravel scopes part.

I have a user model and table.

How can I assign a user the role of user, customer and/or admin.

I hav

6条回答
  •  鱼传尺愫
    2020-11-28 21:40

    Thanks for this, this question was riddling my mind for a while! I took Raymond Lagonda's solution customised it a little for Laravel 5.6, using the built-in rate limiting, using a single thirdparty client (or be more custom if needed), while still giving each user a list of permissions (scopes).

    • Uses Laravel Passport password grant and follows Oauth flow
    • Gives you ability to set roles (scopes) for different users
    • don't expose/release client ID or client secret, only the user's username (email) and password, pretty much a password grant, minus the client/grant stuff

    Examples at bottom

    routes/api.php

        Route::group(['namespace' => 'ThirdParty', 'prefix' => 'thirdparty'], function () {
            Route::post('login', 'ApiLoginController@login');
        });
    

    ThirdParty/ApiLoginController.php

    hasTooManyLoginAttempts($request)) {
                $this->fireLockoutEvent($request);
    
                return $this->sendLockoutResponse($request);
            }
    
            $user = $this->validateUserLogin($request);
    
            $client = ThirdParty::where(['id' => config('thirdparties.client_id')])->first();
    
            $request->request->add([
                'scope' => $user->scopes,
                'grant_type' => 'password',
                'client_id' => $client->id,
                'client_secret' => $client->secret
            ]);
    
            return Route::dispatch(
                Request::create('/oauth/token', 'post')
            );
        }
    
        /**
         * Validate the users login, checking
         * their username/password
         *
         * @param  Request $request
         * @return User
         */
        public function validateUserLogin($request)
        {
            $this->incrementLoginAttempts($request);
    
            $username = $request->username;
            $password = $request->password;
    
            $user = User::where(['email' => $username])->first();
    
            abort_unless($user, 401, 'Incorrect email/password.');
    
            $user->setVisible(['password']);
    
            abort_unless(Hash::check($password, $user->password), 401, 'Incorrect email/password.');
    
            return $user;
        }
    }
    

    config/thirdparties.php

     env('THIRDPARTY_CLIENT_ID', null),
    ];
    

    ThirdParty.php

    .env

    ## THIRDPARTIES
    THIRDPARTY_CLIENT_ID=3
    

    php artisan make:migration add_scope_to_users_table --table=users

            // up
            Schema::table('users', function (Blueprint $table) {
                $table->text('scopes')->nullable()->after('api_access');
            });
            // down
            Schema::table('users', function (Blueprint $table) {
                $table->dropColumn('scopes');
            });
    

    (note: api_access is a flag which decides whether a user can login to the website/frontend portion of the app, to view dashboards/records etc.),

    routes/api.php

    Route::group(['middleware' => ['auth.client:YOUR_SCOPE_HERE', 'throttle:60,1']], function () {
        ...routes...
    });
    

    MySQL - Users scopes

    INSERT INTO `users` (`id`, `created_at`, `updated_at`, `name`, `email`, `password`, `remember_token`, `api_access`, `scopes`)
    VALUES
        (5, '2019-03-19 19:27:08', '2019-03-19 19:27:08', '', 'hello@email.tld', 'YOUR_HASHED_PASSWORD', NULL, 1, 'YOUR_SCOPE_HERE ANOTHER_SCOPE_HERE');
    
    

    MySQL - ThirdParty Oauth Client

    INSERT INTO `oauth_clients` (`id`, `user_id`, `name`, `secret`, `redirect`, `personal_access_client`, `password_client`, `revoked`, `created_at`, `updated_at`)
    VALUES
        (3, NULL, 'Thirdparty Password Grant Client', 'YOUR_SECRET', 'http://localhost', 0, 1, 0, '2019-03-19 19:12:37', '2019-03-19 19:12:37');
    

    cURL - Logging in/requesting a token

    curl -X POST \
      http://site.localhost/api/v1/thirdparty/login \
      -H 'Accept: application/json' \
      -H 'Accept-Charset: application/json' \
      -F username=hello@email.tld \
      -F password=YOUR_UNHASHED_PASSWORD
    
    {
        "token_type": "Bearer",
        "expires_in": 604800,
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciO...",
        "refresh_token": "def502008a75cd2cdd0dad086..."
    }
    

    Use longlived access_token/refresh_token as normal!

    Accessing forbidden scope

    {
        "data": {
            "errors": "Invalid scope(s) provided."
        },
        "meta": {
            "code": 403,
            "status": "FORBIDDEN"
        }
    }
    

提交回复
热议问题