php接口应提前拦截并自动续期token,而非等待401报错;需结合refresh_token、前置过期检测(jwt解码exp或expires_in计算)、安全存储(aes加密+设备指纹)及中间件统一刷新逻辑。

PHP接口遇到token过期,关键不是等报错再处理,而是提前拦截、自动续期。核心在于用好refresh_token + 合理的检测时机 + 安全的存储更新逻辑。
Token过期检测要前置,别等401才反应
靠接口返回401再去刷新,用户体验差,还可能因并发请求导致多次刷新冲突。更稳妥的做法是:在每次发起请求前,先本地判断access_token是否即将失效。
- 如果token是JWT格式,直接base64解码payload,读取exp(过期时间戳),对比time() + 缓冲值(如60秒)是否已超;
- 如果token不含exp,就依赖服务端返回的expires_in字段和created时间戳计算;
- 建议预留30–60秒缓冲,避免网络延迟导致刚发请求就过期。
刷新流程必须带refresh_token且服务端支持
自动刷新不是客户端单方面能完成的,前提是首次登录时已获取到有效的refresh_token,且服务端开放了/auth/refresh这类刷新接口。
- 调用刷新接口时,需携带refresh_token、client_id、client_secret(若需要);
- 成功响应应包含新的access_token、新的refresh_token(部分服务会轮换)、expires_in;
- 务必用新refresh_token覆盖旧值——有些平台每次刷新都会发放新refresh_token,旧的会立即失效。
服务端存储refresh_token要安全且可绑定
不能把refresh_token明文存数据库或配置文件里。它相当于长期通行证,泄露等于账号失控。
- 推荐用AES加密后存入MySQL或PostgreSQL,密钥从环境变量读取;
- 生产环境建议结合设备指纹(如User-Agent哈希+IP段+App ID)存入Redis,键名类似refresh:{user_id}:{device_fingerprint};
- 每次刷新后更新Redis过期时间(比如设为7天),并记录最后使用时间,异常频次触发风控。
PHP代码层面推荐封装成统一中间件
避免每个控制器都重复写刷新逻辑。以Laravel或ThinkPHP为例,可在请求进入业务逻辑前统一拦截:
- 从Header或Cookie中提取当前access_token;
- 校验是否过期,若临近过期,调用封装好的refreshAccessToken()方法;
- 刷新成功后,更新本地缓存(如APCu)和持久化存储,并把新token注入后续请求头;
- 若refresh_token也失效,返回标准错误码(如401 + code: "refresh_failed"),前端跳转重新授权。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











