exp = Config::get('jwt.ttl', 7200); } /** * 生成 JWT Token(适配 thans/jwt) * @param User $user 用户模型实例 * @return string * @throws RuntimeException */ public function generateToken(User $user): string { // 严格校验参数类型 if (!$user instanceof User) { throw new RuntimeException('生成Token失败:必须传入 User 模型实例'); } try { // 构建 JWT 载荷(thans/jwt 支持数组格式) $payload = [ 'sub' => $user->id, // 主题(用户ID) 'user_id' => $user->id, // 自定义字段:用户ID 'iat' => time(), // 签发时间 'exp' => time() + $this->exp, // 过期时间 'iss' => Config::get('app.app_name', 'admin_system'), // 签发者 ]; // 生成 Token(thans/jwt 核心方法) $token = JWT::builder($payload); // 缓存 Token(区分普通用户/商家) $cacheKey = $user->is_store == 0 ? "user_{$user->id}_jwt" : "store_{$user->id}_jwt"; // TP 缓存:set 方法存储,过期时间与 Token 一致 Cache::set($cacheKey, $token, $this->exp); return $token; } catch (JWTException $e) { throw new RuntimeException('生成JWT Token失败:'.$e->getMessage()); } } /** * 验证 JWT Token 有效性(适配 thans/jwt) * @param string $token JWT Token 字符串(支持带/不带 Bearer 前缀) * @return array|null 解码后的载荷数组(无效返回null) */ public function validateToken(string $token): ?array { // 预处理 Token:移除 Bearer 前缀 $token = trim(str_replace('Bearer ', '', $token)); if (empty($token)) { return null; } try { // 验证并解码 Token(thans/jwt 核心方法) $payload = JWT::verify($token); // 额外校验:缓存中的 Token 是否一致(防止注销/伪造) if (isset($payload['user_id'])) { $user = User::find($payload['user_id']); if ($user) { $cacheKey = $user->is_store == 0 ? "user_{$user->id}_jwt" : "store_{$user->id}_jwt"; $cacheToken = Cache::get($cacheKey); // 缓存无 Token 或不一致,视为无效 if ($cacheToken !== $token) { return null; } } } return (array)$payload; } catch (JWTException $e) { // 捕获 thans/jwt 专属异常(过期、签名错误、格式错误等) return null; } } /** * 注销 Token(清除缓存) * @param User $user 用户模型实例 * @return bool */ public function invalidateToken(User $user): bool { $cacheKey = $user->is_store == 0 ? "user_{$user->id}_jwt" : "store_{$user->id}_jwt"; return Cache::delete($cacheKey); } /** * 刷新 Token(续期,thans/jwt 内置支持) * @param string $oldToken 旧 Token * @return string|null 新 Token(无效返回null) */ public function refreshToken(string $oldToken): ?string { $oldToken = trim(str_replace('Bearer ', '', $oldToken)); if (empty($oldToken)) { return null; } try { // 验证旧 Token 并生成新 Token(自动续期) $newToken = JWT::refresh($oldToken); // 更新缓存中的 Token $payload = JWT::verify($oldToken); if (isset($payload['user_id'])) { $user = User::find($payload['user_id']); if ($user) { $cacheKey = $user->is_store == 0 ? "user_{$user->id}_jwt" : "store_{$user->id}_jwt"; Cache::set($cacheKey, $newToken, $this->exp); } } return $newToken; } catch (JWTException $e) { return null; } } }