setTimestamp($now->getTimestamp() + $expiresIn); return new static( accessToken: $accessToken, refreshToken: $refreshToken, expiresIn: $expiresIn, jti: $payload['jti'] ?? '', id: (string)($payload['id'] ?? ''), clientType: $payload['client'] ?? '', issuedAt: $now, expiresAt: $expiresAt, payload: $payload, ); } /** * 从请求中解析 Token * * 支持多种格式: * 1. Header: Authorization: Bearer * 2. Header: Authorization: * 3. 参数: access_token= * 4. 参数: token= * * @return string|null */ public static function fromRequest(): ?string { // 1. Header Authorization Bearer $auth = request()->header('Authorization', ''); if (!empty($auth)) { if (str_starts_with($auth, 'Bearer ')) { return substr($auth, 7); } // 直接是 token return $auth; } // 2. 参数 access_token $token = request()->input('access_token'); if (!empty($token)) { return $token; } // 3. 参数 token $token = request()->input('token'); if (!empty($token)) { return $token; } return null; } /** * 解析 Token 字符串 * * @param string $tokenString JWT token 字符串 * @param int $expiresIn 有效期(秒) * @param array $payload 载荷数据 * @return static */ public static function parse(string $tokenString, int $expiresIn, array $payload = []): static { return static::create($tokenString, '', $expiresIn, $payload); } /** * 获取访问令牌 */ public function getAccessToken(): string { return $this->accessToken; } /** * 获取刷新令牌 */ public function getRefreshToken(): string { return $this->refreshToken; } /** * 获取用户ID(雪花ID) */ public function getId(): string { return $this->id; } /** * 获取客户端类型 */ public function getClientType(): string { return $this->clientType; } /** * 获取令牌唯一标识 */ public function getJti(): string { return $this->jti; } /** * 获取过期时间戳 */ public function getExpiresAt(): int { return $this->expiresAt->getTimestamp(); } /** * 检查是否已过期 */ public function isExpired(): bool { return time() >= $this->expiresAt->getTimestamp(); } /** * 获取剩余有效期(秒) */ public function getRemainingTime(): int { $remaining = $this->expiresAt->getTimestamp() - time(); return max(0, $remaining); } /** * 转换为数组 */ public function toArray(): array { return [ 'token_type' => $this->tokenType, 'access_token' => $this->accessToken, 'refresh_token' => $this->refreshToken, 'expires_in' => $this->expiresIn, 'expires_at' => $this->expiresAt->format('Y-m-d H:i:s'), 'jti' => $this->jti, 'id' => $this->id, 'client_type' => $this->clientType, 'issued_at' => $this->issuedAt->format('Y-m-d H:i:s'), ]; } /** * 转换为前端格式 */ public function toFrontend(): array { return [ 'token' => $this->accessToken, 'refresh_token' => $this->refreshToken, 'expires_in' => $this->expiresIn, 'expires_at' => $this->expiresAt->getTimestamp(), 'token_type' => $this->tokenType, ]; } /** * JSON 序列化 */ public function jsonSerialize(): array { return $this->toArray(); } }