jwt鉴权需手动拦截请求,thinkphp不内置校验逻辑,须在中间件或initialize()中解析authorization头、验证签名与有效期;漏检将致鉴权失效,常见错误包括token格式错、过期未验、未携token静默放行。

JWT鉴权必须手动拦截请求,ThinkPHP默认不自动校验
ThinkPHP本身不内置JWT验证逻辑,firebase/php-jwt只是个解码/签发工具,你得自己在中间件或控制器里读取Authorization头、解析token、检查有效期和签名——漏掉任一环节都会导致鉴权失效。
常见错误现象:Uncaught InvalidArgumentException: Wrong number of segments(token格式不对)、ExpiredException(没校验exp)、静默放行未携带token的请求(因没写拦截逻辑)。
- 使用场景:API接口统一鉴权,尤其前后端分离项目,避免session依赖
- 必须在
app/middleware.php中注册自定义中间件,或在控制器initialize()里调用校验函数 - 不要在路由闭包里做JWT校验——无法复用,且容易绕过
安装firebase/php-jwt后,注意PHP版本与算法兼容性
firebase/php-jwt v6.10+ 要求 PHP >= 8.0;若项目还在用 PHP 7.4,只能装 v6.4.0 或降级到 v5.x(但v5不支持PS256等新算法)。
性能影响:RSA签名(如RS256)比HMAC(HS256)慢3–5倍,开发环境用HS256够用,生产环境若需更高安全性才上RSA。
- 安装命令:
composer require firebase/php-jwt:^6.4.0(适配PHP 7.4) - 配置项:
JWT_SECRET必须存进.env,别硬编码在代码里 - 若用
RS256,私钥路径要绝对可靠,file_get_contents()失败会抛DomainException
token解析失败时,别只捕获JWTException,还要处理底层异常
仅用try...catch (JWTException $e)会漏掉UnexpectedValueException(比如token被篡改)、InvalidArgumentException(base64解码失败)等,结果是500而不是401。
真实调试中,常因前端传了Bearer tokenxxx(少空格)或Basic xxx(错用认证类型)导致解析中断。
- 必须同时捕获:
JWTException、UnexpectedValueException、InvalidArgumentException - 解析前先用
preg_match('/^Bearer\s+(.+)$/', $authHeader, $matches)校验格式,再取$matches[1] - 示例片段:
try { $token = JWT::decode($jwt, $key, ['HS256']); } catch (Exception $e) { // 统一返回401 return json(['msg' => 'token invalid'])->code(401); }
刷新token不能只重签发,得结合黑名单或短有效期控制
JWT本身不可撤销,所以“退出登录”或“密码修改后使旧token失效”,不能只删客户端token,必须服务端干预。常见做法是维护一个invalid_tokens表,或把jti字段存Redis并设TTL。
容易踩的坑:把refresh token和access token混用;或者给access token设7天有效期——等于变相放弃主动登出能力。
- access token建议≤2小时,refresh token可设7天,但每次使用后必须更新其
jti并延长TTL - ThinkPHP的
Cache::tag()不适合存黑名单——tag机制不保证原子性,高并发下可能漏删 - 更稳妥的是用Redis的
SET key "" EX 7200 NX存jti,NX确保不重复,EX匹配access token有效期
JWT::encode(),而是没想清楚状态管理该落在哪一层。大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











