hamedov/passport-multiauth

为 Laravel Passport 提供多认证和自定义授权

2.2.5 2021-09-11 14:46 UTC

This package is auto-updated.

Last update: 2024-09-11 21:26:22 UTC


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