albetnov/sanctum-refresh

该扩展包扩展了 sanctum 的能力,使其能够提供刷新令牌

2.0.0-beta 2023-01-27 09:22 UTC

This package is auto-updated.

Last update: 2024-09-24 16:31:42 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads Coverage

一个扩展 Sanctum 以提供刷新令牌的包。

安装

您可以通过 composer 安装此包

composer require albetnov/sanctum-refresh

然后您需要推送并运行迁移

php artisan vendor:publish --tag="sanctum-refresh-migrations"
php artisan migrate

您也可以使用以下命令发布配置文件

php artisan vendor:publish --tag="sanctum-refresh-config"

这是发布配置文件的内容

return [
    /**
     * Set the fallback expiration time of both tokens
     * Time in minutes.
     */
    'expiration' => [
        // set the fallback of access token expiration
        'access_token' => 2, // 2 minutes,
        // set the fallback of refresh token expiration
        'refresh_token' => 30, // 30 minutes
    ],
    /**
     * Configuration of Sanctum Refresh behaviour
     */
    'sanctum_refresh' => [
        /**
         * Custom the api response message
         * array<string, string>
         */
        'message' => [
            // Authenticated successful message to be used by /login route
            'authed' => 'Authentication success!',
            // Invalid or expired refresh token message
            'invalidMsg' => 'Refresh token is expired or invalid.',
        ],
        /**
         * Custom the routes behaviour
         * array<string, string>
         */
        'routes' => [
            // Only show refresh route (hide the login route)
            'refreshOnly' => false,

            /**
             * Custom the routes urls
             * array<string, string>
             */
            'urls' => [
                'login' => '/login',
                'refresh' => '/refresh',
            ],

            /**
             * Custom the routes middlewares
             * array<string, ?array>
             */
            'middlewares' => [
                'login' => null,
                'refresh' => ['checkRefreshToken'],
            ],
        ],
    ],
];

快速开始

使用此包最简单的方法是使用提供的脚手架。

首先,在 App\Http\Kernel 中的 $routeMiddleware 添加提供的中间件

'checkRefreshToken' => Albet\SanctumRefresh\Middleware\CheckRefreshToken

然后,在任意的服务提供者中注册路由,例如 AuthServiceProvider

SanctumRefresh::routes();

之后,路由应该可以通过给定的配置 URL 访问。例如 /login/refresh。或者您也可以通过执行以下操作来查看它

php artisan route:list

如果路由不在带名称前缀的分组内,则路由将注册为 loginrefresh 名称。

login 路由接受 usernameemail 作为用户标识符,并接受 password 作为密码。

另一方面,refresh 路由既不接受 refresh_token cookie 也不接受 refresh_token json body。

上述两个 URL 都可以通过 POST 方法访问。

手动操作

Sanctum Refresh 使您能够轻松地手动将此包与项目集成。

  • 认证脚手架

    Sanctum Refresh 提供了一个认证脚手架,可用于您的自定义控制器。

    Albet\SanctumRefresh\Requests\LoginRequest::class

    LoginRequest 提供了一个 auth() 方法,帮助您通过 usernameemail 和最终 password 认证用户。

  • CheckForRefreshToken

    如果您不想使用 CheckRefreshToken,则无需使用。例如,您可能需要修改中间件如何处理刷新令牌。您可以使用提供的最小代码来实现这一点

    Albet\SanctumRefresh\Helpers\CheckForRefreshToken::check($refreshToken);

    只需将 $refreshToken 作为字符串传递,然后设置即可。助手将为您验证整个流程,并在成功时返回 true,在失败时抛出异常

    Albet\SanctumRefresh\Exceptions\InvalidTokenException::class

    以下是一个使用 CheckRefreshToken 中间件的示例用法

    // Check refresh token.
    $refreshToken = $request->hasCookie('refresh_token') ?
        $request->cookie('refresh_token') :
        $request->get('refresh_token');
    
    if (! $refreshToken) {
        return response()->json([
            'message' => SanctumRefresh::$middlewareMsg,
        ], 400);
    }
    
    try {
        CheckForRefreshToken::check($refreshToken);
    
        return $next($request);
    } catch (InvalidTokenException $e) {
        return response()->json([
            'message' => SanctumRefresh::$middlewareMsg,
            'reason' => $e->getMessage(),
        ], 400);
    }

    以上是 CheckRefreshToken 中间件的代码。

  • 自定义 PersonalAccessToken 模型

    从版本 2 开始,Sanctum Refresh 不再覆盖 Sanctum 中的任何代码。相反,此包将其封装起来。也就是说,您现在可以自由地修改 PersonalAccessToken 模型中的任何内容。如果您想在现有项目中使用此包,这很重要。只需

    use Custom\Models\PersonalAccessToken;
    Albet\SanctumRefresh\SanctumRefresh::usePersonalAccessTokenModel(PersonalAccessToken::class);

    在任意的服务提供者中。但是,该模型必须扩展 Sanctum 的 HasApiToken

    • HasRefreshable Trait(PersonalAccessToken 扩展)

    Sanctum Refresh 还提供了

    Albet\SanctumRefresh\Traits\HasRefreshable::class

    此特质将注入与您的自定义 PersonalAccessToken 模型的关系。

  • TokenIssuer

    与之前一样,SanctumRefresh 也提供了 TokenIssuer

    Albet\SanctumRefresh\Services\TokenIssuer::class

    该类包含两个方法

    Albet\SanctumRefresh\Services\TokenIssuer::issue($model, $name, $config)

    以上方法将生成一个完整的令牌,包括刷新令牌。该方法接受 3 个参数:可令牌模型、令牌名称和最终配置(过期时间等)。

    Albet\SanctumRefresh\Services\TokenIssuer::refreshToken($refreshToken, $name, $config)

    以上方法将重新生成令牌。但与基于可令牌模型不同,此方法将基于给定的刷新令牌重新生成令牌。该方法接受 3 个参数:原始刷新令牌字符串、新的令牌名称和配置(过期时间等)。

    以上两个方法都返回类似以下的 Collection 实例

    [
        accessTokenInstance, 
        refreshTokenInstance,
        plain => [accessToken, refreshToken]
    ]

Sanctum Refresh 还提供了 config_builder() 以更易读的方式生成配置数组。例如用法

TokenIssuer::refreshToken($string, $name, config_builder(
  abilities: ['*'], 
  tokenExpiresAt: now()->addSeconds(30), 
  refreshTokenExpiresAt: now()->addHour()
))
  • 可刷新令牌特性(用户模型)

    不再需要重复将 $model 放入 TokenIssuer 中。您可以直接在用户模型中使用 HasRefreshableToken 特性

    <?php
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    use Laravel\Sanctum\HasApiTokens;
    use Albet\SanctumRefresh\Traits\HasRefreshableToken;
    
    class User extends Model {
        use HasApiTokens, HasFactory, HasRefreshableToken;
    ...

    以上是您最终的用户模型的样子。

    此特性将为您提供2个方法。

    • createTokenWithRefresh($name, $config)

      创建访问令牌以及刷新令牌。它是围绕 TokenIssuer::issue() 的包装,无需 $model

    • revokeBothTokens()

      撤销访问令牌和刷新令牌。

  • RefreshTokenRepository

    最后,Sanctum Refresh 还为您提供了一个仓库。正如其名所暗示的,这个仓库将帮助您撤销刷新令牌(不撤销访问令牌)。此仓库提供了2个方法。

    • 根据给定ID撤销刷新令牌

      revokeRefreshTokenFromTokenId($id) 将从给定的 $id 撤销/删除刷新令牌。此 $id 必须是 RefreshToken 表的 ID。

    • 从明文令牌撤销刷新令牌

      revokeRefreshTokenFromToken($stringToken) 将从给定的明文令牌撤销/删除刷新令牌。

就这么多!

测试

运行测试

composer test

了解代码覆盖率

composer test-coverage

变更日志

请参阅变更日志获取更多信息。

贡献

您可以为这个项目做出贡献。

致谢

许可证

MIT许可证(MIT)。请参阅许可证文件获取更多信息。