Laravel Passport为第一方应用授予Flow

Mar*_*arc 12 php security oauth-2.0 laravel laravel-passport

我正在使用Laravel Passport来访问我的API的某些部分到第三方应用程序.

但是,我也通过自己的第一方原生Android应用程序使用自己的API.因此,在这种情况下,我查看整个互联网以获得最佳实践,但是仍然坚持得出结论.

以下是我发现的可能性:

可能性#01

我可以按照用户凭据密码授予流程.
在这种情况下,我需要传递一个client_secretclient_id授权服务器.为了保证他们的安全,我不能在我的移动应用程序的源代码中编写它们(APK可以解密...).

所以,我有两个选择.

可能性#01 - 选择A.

在调用oauth端点之前,通过我自己的服务器代理并注入秘密:

$proxy = Request::create('/oauth/token', 'post', [
    'grant_type' => 'password',
    'client_id' => 1,
    'client_secret' => 'myownclientsecretishere',
    'username' => $username,
    'password' => $password
]);
$proxy->headers->set('Accept', 'application/json');
$response = app()->handle($proxy);
Run Code Online (Sandbox Code Playgroud)

可能性#01 - 选择B.

使用中间件调用oauth端点时注入秘密:

class InjectPasswordGrantSecret
{
    public function handle($request, Closure $next)
    {
        $request->request->add([
            'client_id' => 1,
            'client_secret' => 'myownclientsecretishere'
        ]);
        return $next($request);
    }
}
Run Code Online (Sandbox Code Playgroud)

这些是工作示例,但它们在资源方面也很贪婪.我尝试在本地计算机上使用Apache基准测试,我得到了9个请求/秒.

可能性#02

我可以关注个人访问资助.
这个看起来不像OAuth2中的标准,它允许我们通过任何自定义路线创建一个令牌,就像这样:

if (! auth()->attempt(compact('username', 'password'))) {
    return error_response(__('auth.failed'));
}
$user = auth()->user();
$token = $user->createToken(null)->accessToken;
Run Code Online (Sandbox Code Playgroud)

使用Apache基准测试我得到了更好的结果(类似于30个请求/秒).

但是,令牌生存期默认情况下不可配置,并设置为1年(请注意,有一些解决方法可以使用自定义提供程序配置此生命周期).

我真的很想知道这个解决方案是否适用于生产环境.

最初,我使用JWT tymon库,因为我只有自己的应用程序.但现在我需要让它与第一方和第三方应用程序一起工作,我认为OAuth2(通过Laravel Passport)将是一个很好的解决方案......

我希望有人可以帮助我解决这个问题,并解释一下什么是一个很好的解决方案,让它在生产服务器上安全地[并非慢慢地]工作.

pat*_*cus 0

我之前所做的是实现我自己的控制器,该控制器扩展了Laravel\Passport\Http\Controllers\AccessTokenController. 您不仅可以设置此控制器来处理创建令牌,还可以添加用于刷新和撤销令牌的路由。

例如,我有一个create用于显示登录表单的方法、一个store用于创建访问令牌的方法、一个refresh用于使用刷新令牌刷新过期访问令牌的方法,以及一个revoke用于撤销提供的访问令牌和相关刷新令牌的方法。

由于该项目不是开源的,我无法提供确切的代码,但这是一个快速示例控制器,仅包含以下store方法:

use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Laravel\Passport\Http\Controllers\AccessTokenController;

class MyAccessTokenController extends AccessTokenController
{
    public function store(Request $request, ServerRequestInterface $tokenRequest)
    {
        // update the request to force your grant type, id, secret, and scopes
        $request->request->add([
            'grant_type' => 'password',
            'client_id' => 'your-client-id',
            'client_secret' => 'your-client-secret',
            'scope' => 'your-desired-scopes',
        ]);

        // generate the token
        $token = $this->issueToken($tokenRequest->withParsedBody($request->request->all()));

        // make sure it was successful
        if ($token->status() != 200) {
            // handle error
        }

        // return the token
        return $token;
    }
}
Run Code Online (Sandbox Code Playgroud)

方法refresh基本上是相同的,但grant_type会是refresh_token.

revoke方法将获取经过身份验证的用户的令牌($token = $request->user()->token(),撤销它($token->revoke()),然后手动浏览oauth_refresh_tokens表中的相关令牌(access_token_id= $token->id)并将revoked字段更新为true

创建一些路由来使用您的自定义控制器,然后就可以开始了(注意:该revoke路由将需要auth:api中间件)。

  • 您能解释一下是什么使得这比简单地使用个人访问授权或其他解决方案更好吗? (4认同)