hamedov / passport-multiauth
为 Laravel Passport 提供多认证和自定义授权
2.2.5
2021-09-11 14:46 UTC
Requires
- php: ^7.2
- laravel/passport: ^8.0
README
本包简单允许您使用 Laravel Passport 认证除了 App\User 之外的其他模型。
注意:从 9.x 版本开始,多认证已集成到 Laravel Passport 中,因此本包可用于 8.x 版本。如果您仍然需要自定义授权功能,请使用此包:https://github.com/hamedov93/passport-grants
安装
composer require hamedov/passport-multiauth
- 本包会覆盖
PassportServiceProvider
,因此您应该从 config/app.php 的 providers 部分中移除它。
用法
- 将您的 guards 和 providers 添加到 config/auth.php
'guards' => [
...
'admin' => [
'driver' => 'passport',
'provider' => 'admins',
'hash' => false,
],
],
'providers' => [
...
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
- 将
guard
参数添加到您的令牌请求中
使用 guzzle http 的示例
$http = new \GuzzleHttp\Client;
$response = $http->post(config('app.url') . '/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('api.password_client_id'),
'client_secret' => config('api.password_client_secret'),
'username' => 'username@example.com',
'password' => 'userpassword',
'scope' => '',
'guard' => 'admin',
],
]);
$data = json_decode((string)$response->getBody(), true);
- 使用 auth 中间件和所需的 guard 认证您的模型,如下所示
Route::middleware('auth:admin')->get('/user', function (Request $request) {
return $request->user();
});
- 刷新令牌请求不需要额外的参数。
- 当然,所有模型都必须扩展
Illuminate\Foundation\Auth\User
并使用Laravel\Passport\HasApiTokens
特性。 - 这就完成了。
撤销访问令牌
$model = auth()->user();
// Get model/user access token
$accessToken = $model->token();
// Revoke access token
DB::table('oauth_refresh_tokens')->where('access_token_id', $accessToken->id)->update([
'revoked' => true
]);
$accessToken->revoke();
警告
- 依赖于
oauth_access_tokens
表的关系,如$user->tokens()
和$token->user();
,尚未实现多认证且无法使用,您通常也不需要它们。然而,它们将在未来的版本中实现。
自定义授权
- 创建一个新的自定义授权
我们将以 Facebook 登录为例
php artisan make:grant FacebookGrant
这将在 App\Grants 文件夹中创建一个新的授权类
- 指定您授权的唯一标识符
protected $identifier = 'facebook';
- 指定您将在访问令牌请求中发送的参数,而不是用户名和密码
protected $request_params = [
'facebook_access_token',
];
访问令牌请求应如下所示
$response = $http->post(env('APP_URL') . '/oauth/token', [
'form_params' => [
'grant_type' => 'facebook',
'client_id' => config('api.password_client_id'),
'client_secret' => config('api.password_client_secret'),
'facebook_access_token' => 'facebook access token',
'scope' => '',
'guard' => 'api',
],
]);
- 接下来,将您的认证逻辑添加到
getUserEntityByRequestParams
方法中
您将作为第一个参数接收到已认证模型的空实例。
第二个参数是一个关联数组,包含 request_params
属性中指定的参数值。
- 方法实现应类似于以下内容
protected function getUserEntityByRequestParams(Model $model, $request_params,
$guard, $grantType, ClientEntityInterface $clientEntity)
{
// Do your logic to authenticate the user.
// Return false or void if authentication fails.
// This will throw OAuthServerException.
$facebook_access_token = $request_params['facebook_access_token'];
// Contact facebook server to make sure the token is valid and get the corresponding user profile.
$profile = file_get_contents('https://graph.facebook.com/me?fields=name,email&access_token='.$facebook_access_token);
$profile = (array) json_decode($profile);
if ( ! isset($profile['email']))
{
// We cannot identify the user without his email address
return;
}
// Retrieve user or any authenticatable model by email or create new one.
$user = $model->firstOrCreate(['email' => $profile['email']], ['name' => $profile['name']]);
return new User($user->getAuthIdentifier());
}
- 您可以使用之前的示例为任何可认证实体使用,无需任何区别,只需在令牌请求中提供 guard 参数,实现您的认证逻辑,并在认证失败时返回 void/false 或在成功时返回 Laravel\Passport\Bridge\User 的实例。
许可证
在 Mit 许可证下发布,请参阅 LICENSE