Mar*_*arc 12 php security oauth-2.0 laravel laravel-passport
我正在使用Laravel Passport来访问我的API的某些部分到第三方应用程序.
但是,我也通过自己的第一方原生Android应用程序使用自己的API.因此,在这种情况下,我查看整个互联网以获得最佳实践,但是仍然坚持得出结论.
以下是我发现的可能性:
我可以按照用户凭据密码授予流程.
在这种情况下,我需要传递一个client_secret和client_id授权服务器.为了保证他们的安全,我不能在我的移动应用程序的源代码中编写它们(APK可以解密...).
所以,我有两个选择.
在调用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)
使用中间件调用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个请求/秒.
我可以关注个人访问资助.
这个看起来不像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)将是一个很好的解决方案......
我希望有人可以帮助我解决这个问题,并解释一下什么是一个很好的解决方案,让它在生产服务器上安全地[并非慢慢地]工作.
我之前所做的是实现我自己的控制器,该控制器扩展了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中间件)。
| 归档时间: |
|
| 查看次数: |
1294 次 |
| 最近记录: |