yivoff / jwt-refresh-bundle
JWT令牌刷新。独立于持久层,分割id/has进行验证
Requires
- php: >=8.1
- lexik/jwt-authentication-bundle: ^v2.20.3
- symfony/config: ^6.3|^7.0.0
- symfony/dependency-injection: ^6.3|^7.0.0
- symfony/framework-bundle: ^6.3|^7.0.0
Requires (Dev)
- bamarni/composer-bin-plugin: ^1.8.2
- nyholm/symfony-bundle-test: dev-master
- symfony/console: ^6.3|^7.0.0
Suggests
- symfony/console: ^6.3|^7.0.0
README
描述
此包提供了一种生成“刷新令牌”的方法,用户可以使用它来获取新的授权令牌(JWT),当之前的令牌过期时。这是[lexik/LexikJWTAuthenticationBundle]的配套工具,不能单独使用。
该包不假设存储刷新令牌的持久层。只要存在实现包提供的基本接口的服务,就可以使用任何后端或库(MySQL、Mongo、Redis、flat-file等):RefreshTokenProviderInterface
令牌以标识符和哈希验证器存储,而不是纯文本验证器,以增加安全性。
每个刷新令牌只能使用一次来获取新的认证令牌。使用后,旧刷新令牌将被删除,并生成新的刷新令牌。
应该为刷新令牌设置一个比认证令牌的生存时间显著更长的存活时间。
要求
需要PHP 8+、Symfony 5.3+
安装和设置
安装
$ composer require yivoff/jwt-refresh-bundle
令牌提供者实现
此包不对令牌提供者的性质做任何假设。为了能够使用它,您需要实现自己的,无论是常规的Doctrime ORM存储库还是适合您项目的任何其他东西。
您需要一个实现RefreshTokenProviderInterface
的服务,然后在包配置中,在yivoff_jwt_refresh.token_provider_service
上写下包将用于获取/添加/删除令牌的服务ID。
此服务直接或间接地负责与您的选择持久层进行调解,并应返回/接受RefreshTokenInterface
实例。或者您的应用程序令牌实体直接实现此接口,或者您的令牌提供者适应您本地的实体和提供的RefreshToken
类。
可清除提供者
您的令牌提供者可以另外实现PurgableRefreshTokenProviderInterface
,以便有清除所有过时令牌的便利方法。如果您想使用包含的清除命令,这是必要的。
安全集成
在JWT认证器提供登录检查的同一步骤中,设置由本包提供的新守卫认证器(Yivoff\JwtTokenRefresh\Security\Authenticator
)。
例如,对于典型的配置
firewalls: login: pattern: ^/login stateless: true anonymous: true provider: users_in_memory custom_authenticators: - Yivoff\JwtTokenRefresh\Security\Authenticator json_login: check_path: /login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure
注意firewall.login.guard.authenticators
的内容。
包配置
Yaml
yivoff_jwt_refresh: token_provider_service: 'App\Repository\AuthRefreshTokenRepository' token_ttl: 3600 parameter_name: 'refresh_token'
XML
<yivoff_jwt_refresh xmlns="https://yivoff.com/schema/dic/jwt_refresh_bundle"> <provider_service>App\Infrastructure\Redis\Repository\AuthRefreshTokenRepository</provider_service> <parameter_name>refresh_token</parameter_name> <token_ttl>3600</token_ttl> </yivoff_jwt_refresh>
-
token_provider_service
这是一个
required
键。字符串值必须是实现RefreshTokenProviderInterface
的服务id
。 -
token_ttl
该包提供了默认值3600。如果需要令牌可用时间更长或更短,请更改它。
-
parameter_name
将持有刷新令牌的HTTP
POST
参数的名称。默认为refresh_token
。
清除命令
如果您的项目已安装 symfony/console
,并且您的令牌提供者实现了 PurgableRefreshTokenProviderInterface
,则可以使用命令删除所有已过期的现有令牌。
可以通过运行 bin/console yivoff:jwt_refresh:purge_expired_tokens
来执行此命令。在没有错误的情况下,它不会产生任何输出。
用法
在任何常规的JSON身份验证中,该组件将在配置中定义的名为 parameter_name
的字段上注入刷新令牌。典型的请求/响应将是
请求
POST https://:7099/login_check Content-Type: application/json { "username": "john_user", "password": "abcd" }
响应
HTTP/1.1 200 OK Date: Sat, 09 May 2020 16:01:37 GMT Connection: close Content-Type: application/json { "token": "ey...token...131", "refresh_token": "bd8b1a304dc39dda3d10a38788b2ebf7:f52ac998773d552a0c639c2f85ffa5f2e18df2f1a3f528c9ddc3fcd8c6ba2f31" }
不需要为“刷新”路径注册新的路由。要获取新的身份验证JWT,您只需使用具有相同名称和值的常规 POST
调用相同的登录路径即可
POST https://:7099/login_check Content-Type: application/x-www-form-urlencoded refresh_token=bd8b1a304dc39dda3d10a38788b2ebf7:f52ac998773d552a0c639c2f85ffa5f2e18df2f1a3f528c9ddc3fcd8c6ba2f31
事件
如果您希望您的应用程序对成功的或失败的刷新尝试(记录等)做出反应,则库会发出您可以监听的事件。
失败
当刷新尝试因任何原因失败时,库会发出一个 Yivoff\JwtRefreshBundle\Event\JwtRefreshTokenFailed
事件。
事件有三个公共属性
?string tokenId
:刷新令牌的标识符。如果有效载荷无效,并且无法从请求中检索标识符,则为null。?string userIdentifier
:拥有令牌的用户的标识符。如果有效载荷无效,或者我们无法找到请求tokenId
的令牌,则为null。FailType $failType
:这是一个枚举,描述了遇到的失败类型FailType::PAYLOAD
:无法解析有效载荷。FailType::NOT_FOUND
:找不到具有该id的令牌。FailType::INVALID
:找到了令牌,但验证器无效。FailType::EXPIRED
:找到了令牌,但它已经过期。
成功
在成功的情况下,会发出一个 Yivoff\JwtRefreshBundle\Event\JwtRefreshTokenSucceeded
事件。这仅包括以下属性
string tokenId
:刷新令牌的标识符string userIdentifier
:拥有令牌的用户的标识符