|
|
@@ -12,52 +12,50 @@ use think\Cache;
|
|
|
class AuthHook
|
|
|
{
|
|
|
public const string TOKEN_REVOKE = 'token_revoke:';
|
|
|
-
|
|
|
- private int $expireIn;
|
|
|
+ public const string TOKEN_INFO = 'token_info:';
|
|
|
|
|
|
public function __construct(private Cache $cache)
|
|
|
{
|
|
|
- $this->expireIn = Auth::getConfig()['expire_in'];
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Token生成时在Redis中记录token信息,方便服务端查看token状态
|
|
|
+ */
|
|
|
#[Hook("token_generate")]
|
|
|
public function generateToken($payload): void
|
|
|
{
|
|
|
- $this->renewToken($payload);
|
|
|
+ $this->cache->remember(self::TOKEN_INFO . $payload->jti, (array) $payload, $payload->exp - time());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * Token验证时检查是否被提前撤销
|
|
|
* @throws \ExpiredException
|
|
|
*/
|
|
|
#[Hook("token_verify")]
|
|
|
public function checkToken($payload): void
|
|
|
{
|
|
|
- if ($this->cache->has(self::TOKEN_REVOKE . $payload->jti)
|
|
|
- && $this->cache->get(self::TOKEN_REVOKE . $payload->jti) > time() - Auth::SLEEP_WAY) {
|
|
|
- // 未过期可以续期
|
|
|
- $this->renewToken($payload);
|
|
|
- return;
|
|
|
+ $revokeTime = $this->cache->get(self::TOKEN_REVOKE . $payload->jti);
|
|
|
+
|
|
|
+ // token被撤销且超过SLEEP_WAY时间,拒绝访问
|
|
|
+ if ($revokeTime !== null && $revokeTime <= time() - Auth::SLEEP_WAY) {
|
|
|
+ $ex = new ExpiredException('Token expired early');
|
|
|
+ $ex->setPayload($payload);
|
|
|
+ $ex->setTimestamp($payload->exp);
|
|
|
+ throw $ex;
|
|
|
}
|
|
|
- $ex = new ExpiredException('Expired token');
|
|
|
- $ex->setPayload($payload);
|
|
|
- $ex->setTimestamp($payload->exp);
|
|
|
- throw $ex;
|
|
|
- }
|
|
|
-
|
|
|
- #[Hook("token_revoke")]
|
|
|
- public function revokeToken($payload): void
|
|
|
- {
|
|
|
- $this->cache->remember(self::TOKEN_REVOKE . $payload->jti, time(), $payload->exp - time() + Auth::SLEEP_WAY);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param $payload
|
|
|
- * @return void
|
|
|
- * @throws \Throwable
|
|
|
+ * Token被撤销时,在Redis中存储撤销标记,并清除token信息
|
|
|
+ * 撤销标记的TTL设置为token剩余有效期,确保撤销记录在token过期后自动清除
|
|
|
*/
|
|
|
- public function renewToken($payload): void
|
|
|
+ #[Hook("token_revoke")]
|
|
|
+ public function revokeToken($payload): void
|
|
|
{
|
|
|
- $exp = time() + $this->expireIn;
|
|
|
- $this->cache->remember(self::TOKEN_REVOKE . $payload->jti, $exp, $this->expireIn + Auth::SLEEP_WAY);
|
|
|
+ $remainingTime = $payload->exp - time();
|
|
|
+ if ($remainingTime > 0) {
|
|
|
+ $this->cache->remember(self::TOKEN_REVOKE . $payload->jti, time(), $remainingTime);
|
|
|
+ $this->cache->delete(self::TOKEN_INFO . $payload->jti);
|
|
|
+ }
|
|
|
}
|
|
|
}
|