如何使用Laravel Passport Scopes + Password Grant Type限制用户操作

问题描述 投票:9回答:3

我已经为官方文档(https://laravel.com/docs/5.3/passport#introduction)中描述的Laravel 5.3设置了Laravel Passport包。

我希望API由移动应用程序使用,因此我尝试实现密码授予令牌。我创建了一个密码授予客户端,以及令牌请求进程......

$response = $http->post('http://my-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => '[email protected]',
        'password' => 'my-password',
        'scope' => '',
    ],
]);

...按预期工作,为我的一个用户返回访问令牌和刷新令牌。

但是现在我想定义一些范围,以便限制用户的访问权限......再次按照文档,我在AuthServiceProvider.php的启动方法中定义它们,如:

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

在这种情况下,如果“恶意”普通用户请求一个令牌(使用上面的POST调用)指定'scope' => 'admin',他或她将获得一个“管理员”令牌......这不是我想要的。

因此,我想知道在这种情况下工作流如何有效地限制对普通用户的访问,以及我在哪里实现范围验证逻辑。

提前致谢。

php laravel oauth-2.0 laravel-5.3 laravel-passport
3个回答
5
投票

解决这个问题的一种方法是创建一个中间件

例如,如果您只希望拥有来自example.com的电子邮件的用户请求管理域,您可以执行类似的操作

示例ScopeLogic.php中间件:

if ($request->input('grant_type') === 'password') {
    $scope = $request->input('scope');
    $username = $request->input('username');

    if ($scope === 'admin' && (strpos($username, '@example.com') === false)) {
        return response()->json(['message' => "Not authorized to request admin scope"], 401);
    }
}

return $next($request);

当然,您必须将此范围添加到Kernel.php中的$ routeMiddleware数组中

protected $routeMiddleware = [
    ...
    'check-scopes' => \App\Http\Middleware\ScopeLogic::class
]

以及在Passport::routes()中包装AuthServiceProvider.php来检查这个中间件

\Route::group(['middleware' => 'check-scopes'], function() {
    Passport::routes();
});

Passport还会检查是否通过了正确的用户名和护照组合,因此您不必担心中间件中的问题


0
投票

在我看来,我认为大多数人对OAuth和API感到困惑的是,范围与“客户”有关,而与“资源所有者”本身无关。如果需要,客户端应该能够使用管理范围与API进行通信,或者根本不使用范围。如果他们将admin-ish类型范围与用户上下文(密码授予,授权代码授权等)一起使用,那么就不会阻止他们在API中进行需要针对该用户的范围的调用。对我来说,唯一真正被归类为恶意的人就是设法窃取包含管理范围的访问令牌的人。这就是为什么允许API实现者指定授予客户端的范围的原因,以及如果它是使用密码授予等内容的第一方应用程序,那么您作为用户别无选择,只能信任它与您的数据。

我不知道怎么会这样做并在另一个移动应用程序中使用检索到的令牌但是如果你尝试用管理范围自己手动请求令牌,那么我真的没有看到任何错误(除了你给出了应用程序更多控制与您设置为用户上下文,所以它甚至可能适得其反?)

如果您需要更多控制权,那么您需要通过API并为资源服务器中的每个用户创建类似应用程序级权限的内容。


0
投票

我忘记了我在哪里阅读它,一些Github在某处发布,但显然Laravel没有内置的那种能力,每个客户端都是平等对待,开箱即用。

用户提供了一个很好的解决方案,我在这里建立了它:https://stackoverflow.com/a/55285483/1132557

© www.soinside.com 2019 - 2024. All rights reserved.