secretKey = config('jwt.jwt_secret_key'); $this->algorithm = config('jwt.jwt_algorithm'); $this->issuer = config('jwt.jwt_issuer'); $this->expiration = config('jwt.jwt_expiration'); } /** * 生成 JWT 令牌 * * @param array $payload * @return string * @throws BusinessException */ public function generateToken(array $payload): string { $defaultPayload = [ // // —— 注册 Claim —— 'iss' => $this->issuer, // 签发者 // 'sub' => 'user_1001', // 面向的用户 // 'aud' => 'api.gateway.example.com', // 接收方 // 'iat' => time(), // 签发时间 // 'nbf' => time(), // 生效时间 // 'exp' => time() + $this->expiration, // 1 小时后过期 'jti' => bin2hex(random_bytes(16)), // 唯一 ID // // —— 自定义 Claim —— // 'uid' => 1001, // 业务用户 ID // 'roles' => ['admin', 'editor'], // 用户角色 // 'meta' => ['region' => 'CN', 'tier' => 5], // 任意自定义数据 ]; $payload = array_merge($defaultPayload, $payload); try { return FirebaseJWT::encode($payload, $this->secretKey, $this->algorithm); } catch (\Exception $e) { throw new BusinessException("令牌生成失败:" . $e->getMessage(), 500); } } /** * 验证 JWT 令牌 * * @param string $token * @return object * @throws BusinessException */ public function verifyToken(string $token) { try { return FirebaseJWT::decode($token, new Key($this->secretKey, $this->algorithm)); } catch (\Firebase\JWT\ExpiredException $e) { throw new BusinessException('令牌已过期', 401); } catch (\Firebase\JWT\SignatureInvalidException $e) { throw new BusinessException('无效的令牌签名', 401); } catch (\Firebase\JWT\BeforeValidException $e) { throw new BusinessException('令牌尚未生效', 401); } catch (\Exception $e) { throw new BusinessException('令牌验证失败:' . $e->getMessage(), 400); } } public function describe() { /* payload 1. 注册 Claim 详解 Claim 名称 含义 类型 建议取值 iss Issuer,发行者,标识该 JWT 的签发主体 string or URI 你的服务域名或项目标识,比如 https://api.example.com sub Subject,主题,标识该 JWT 所面向的用户 string or int 用户在你系统里的唯一 ID aud Audience,受众,标识该 JWT 的接收方 string or array 接收该令牌的服务标识,比如 ["service-a","service-b"] exp Expiration Time,过期时间,Unix 时间戳,到达此时间后不可用 int time() + 3600(1 小时后过期) nbf Not Before,生效时间,Unix 时间戳,表示在此时间之前不可用 int time() 或者 time() + 60(1 分钟后生效) iat Issued At,签发时间,Unix 时间戳 int time() jti JWT ID,JWT 的唯一标识符,用于去重或一次性令牌 string uniqid('', true) 或者 UUID 注意:exp、nbf、iat 必须是整数(秒级时间戳),否则库会抛类型异常或验证失败。 2. 自定义 Claim 除了上面这些“注册”字段,你可以任意添加,比如: php $payload['uid'] = 123; // 业务用户 ID $payload['roles'] = ['admin','user']; // 权限数组 $payload['feature'] = 'beta'; // 标记某个功能开关 这些字段在你的应用程序里可以自由取用。 */ } }