Laravel项目JWT Token过期报401 设TTL为null能否解决问题
问题背景
当前共有三个业务平台:PHP后端、Android应用、iOS应用。其中iOS端用户在使用应用数日后,会出现无法与后端正常通信的问题,经调试排查,故障根因为JWT鉴权返回401状态码,返回「Token is Expired」令牌过期错误。
故障复现样例
示例请求
URL : https://xx.xx.xxx/api/v1/xx header : Accept: application/json parameters : ["userId": xx, "countryId": 0, "deviceType": 1, "pageNo": 1, "token": "xxx", "deviceToken": "xx", "shuffleId": "", "action": 1, "buzcategory": "", "keyWord": "", "socialMediaId": "", "totalCount": 100, "productType": "", "businessName": "", "cityId": 0]
示例响应
{ "error" : "Token is Expired", "status" : 401 }
配置修改方案评估
拟修改的jwt.php配置如下:
'refresh_ttl' => env ('JWT_REFRESH_TTL', Null), 'ttl' => env ('JWT_TTL', NULL), 'required_claims' => [ 'iss', 'iat', // 'exp', 'nbf', 'sub', 'jti', ],
方案效果
这套修改确实可以从技术层面直接消除Token过期报错:
- 将
JWT_TTL设为null后,服务端生成JWT时不会再写入exp(过期时间)字段,生成的Token本身永久有效 - 从
required_claims配置中移除exp后,JWT校验逻辑不会再校验令牌是否过期,自然不会抛出401过期错误
方案风险
这种改法本质是直接关闭了JWT的过期校验机制,属于治标不治本的处理方式,绝对不推荐在生产环境使用:
- 一旦Token发生泄露(包括接口抓包、用户设备遗失、日志泄露等场景),攻击者可以永久使用该Token访问所有受保护接口,没有任何自动失效的手段
- 将
JWT_REFRESH_TTL也设为null会导致刷新令牌同样永久有效,进一步放大安全风险 - 后续如果需要做用户封禁、权限调整等操作,由于Token永久有效,必须额外开发一套Token黑名单存储、校验逻辑,平白增加系统复杂度和维护成本
推荐修复方案
针对iOS端的Token过期问题,更合理的处理方式如下:
- 保留JWT默认的
exp过期校验逻辑,建议将普通访问Token的TTL设置为1-2小时,刷新Token的TTL设置为7-30天,兼顾安全性和用户体验 - 客户端实现全局401状态码拦截逻辑:当接口返回Token过期错误时,自动携带本地存储的刷新Token调用换发接口,获取新的访问Token后自动重试原失败请求,整个过程对用户无感知
- 重点排查iOS端的Token刷新逻辑缺陷:同一套后端鉴权逻辑下Android端未复现同类问题,说明后端逻辑本身无致命问题,大概率是iOS端未实现401自动刷新逻辑,或是刷新Token后未更新本地存储的有效Token,持续使用过期旧Token发起请求才会触发报错。
内容的提问来源于stack exchange,提问作者TharakaNirmana
相关产品推荐
相关产品推荐

