Laravel 护照范围 [英] Laravel Passport Scopes

查看:26
本文介绍了Laravel 护照范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Laravel 范围部分有点困惑.

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.

我有一个带有 vue 和 laravel api 后端的 SPA.我使用 https://laravel.com/docs/5.3/passport#sumption-your-api-with-javascript

I have a SPA with vue and laravel api backend. I use https://laravel.com/docs/5.3/passport#consuming-your-api-with-javascript

    Passport::tokensCan([
        'user' => 'User',
        'customer' => 'Customer',
        'admin' => 'Admin',
    ]);

如何分配哪个用户模型具有哪个范围?

How can i assign which user model has which scope(s)?

还是作用域和角色不一样?

Or are scopes not the same as roles?

您将如何实现这一点?

提前致谢!

推荐答案

还是作用域和角色不一样?

Or are scopes not the same as roles?

两者之间最大的区别在于它们适用的上下文.基于角色的访问控制 (RBAC) 在直接使用网络应用程序时管理用户的访问控制,而 Oauth-2 范围管理对外部客户代表用户.

The biggest difference between the two is the context they apply to. Role-based Access Control (RBAC) governs the access control of a user when using the web application directly, while Oauth-2 scope governs the access to the API resources for an external client on behalf of a user.

如何分配哪个用户模型具有哪个范围?

How can i assign which user model has which scope(s)?

在一般的 Oauth 流程中,用户(作为资源所有者)被要求授权客户端可以代表他/她做和不能做的事情,这些就是您所说的范围.在成功授权后,客户端请求的范围将是分配给生成的令牌而不是用户本身.

In general Oauth flow, a user (as a resource owner) is requested to authorize a client on things that it can and cannot do on his/her behalf, these are what you called scope. On successful authorization the scope being requested by the client will be assigned to the generated token not to the user per se.

根据您选择的 Oauth 授权流程,客户端应在其请求中包含范围.在授权代码授权流程中,当将用户重定向到授权页面时,范围应包含在 HTTP GET 查询参数中,而在密码授权流程中,范围必须包含在 HTTP POST 正文参数中以请求令牌.

Depending on which Oauth grant flow that you choose, the client should include the scope on its request. In Authorization code grant flow the scope should be included on HTTP GET query parameter when redirecting the user to authorization page, while on Password grant flow the scope must be included in HTTP POST body parameter to request a token.

您将如何实现这一点?

这是密码授予流程的示例,假设您已完成laravel/护照事先设置

This is an example with Password grant flow, with assumption that you completed the laravel/passport setup beforehand

定义管理员和用户角色的范围.尽可能具体,例如:管理员可以管理订单,用户只能阅读.

Define scopes for both admin and user role. Be specific as you can, for example: admin can manage-order and user only read it.

// in AuthServiceProvider boot
Passport::tokensCan([
    'manage-order' => 'Manage order scope'
    'read-only-order' => 'Read only order scope'
]);

准备 REST 控制器

Prepare the REST controller

// in controller
namespace AppHttpControllers;

class OrderController extends Controller
{   
    public function index(Request $request)
    {
        // allow listing all order only for token with manage order scope
    }

    public function store(Request $request)
    {
        // allow storing a newly created order in storage for token with manage order scope
    }

    public function show($id)
    {
        // allow displaying the order for token with both manage and read only scope
    }
}

为路由分配 api 防护和作用域

Assign the route with api guard and scope

// in api.php
Route::get('/api/orders', 'OrderController@index')
    ->middleware(['auth:api', 'scopes:manage-order']);
Route::post('/api/orders', 'OrderController@store')
    ->middleware(['auth:api', 'scopes:manage-order']);
Route::get('/api/orders/{id}', 'OrderController@show')
    ->middleware(['auth:api', 'scopes:manage-order, read-only-order']);

并在发出令牌时首先检查用户角色并根据该角色授予范围.为了实现这一点,我们需要一个额外的控制器,它使用 AuthenticatesUsers trait 来提供登录端点.

And when issuing a token check the user role first and grant the scope based on that role. To achieve this, we need an extra controller that use AuthenticatesUsers trait to provide login endpoint.

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use IlluminateFoundationAuthAuthenticatesUsers;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;

class ApiLoginController extends Controller
{
    use AuthenticatesUsers;

    protected function authenticated(Request $request, $user)
    {               
        // implement your user role retrieval logic, for example retrieve from `roles` database table
        $role = $user->checkRole();

        // grant scopes based on the role that we get previously
        if ($role == 'admin') {
            $request->request->add([
                'scope' => 'manage-order' // grant manage order scope for user with admin role
            ]);
        } else {
            $request->request->add([
                'scope' => 'read-only-order' // read-only order scope for other user role
            ]);
        }

        // forward the request to the oauth token request endpoint
        $tokenRequest = Request::create(
            '/oauth/token',
            'post'
        );
        return Route::dispatch($tokenRequest);
    }
}

为api登录端点添加路由

Add route for api login endpoint

//in api.php
Route::group('namespace' => 'Auth', function () {
    Route::post('login', 'ApiLoginController@login');
});

不是对/oauth/token路由做POST,而是POST到我们之前提供的api登录端点

Instead of doing POST to /oauth/token route, POST to the api login endpoint that we provided before

// from client application
$http = new GuzzleHttpClient;

$response = $http->post('http://your-app.com/api/login', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'user@email.com',
        'password' => 'my-password',
    ],
]);

return json_decode((string) $response->getBody(), true);

成功授权后,将根据我们之前定义的范围为客户端应用程序发出 access_token 和 refresh_token.将其保留在某处,并在每次向 API 发出请求时将令牌包含在 HTTP 标头中.

Upon successful authorization, an access_token and a refresh_token based on scope that we define before will be issued for the client application. Keep that somewhere and include the token to the HTTP header whenever making a request to the API.

// from client application
$response = $client->request('GET', '/api/my/index', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

API 现在应该返回

{"error":"unauthenticated"}

每当权限不足的令牌用于消费受限端点时.

whenever a token with under privilege is used to consumed restricted endpoint.

这篇关于Laravel 护照范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆