如何检查用户持有的JWT是否已过期?
如何检查用户持有的JWT是否已过期?
我最近正用PHP搭建第一个带JWT认证的Web应用,摸清楚JWT逻辑的同时,也研究了不少检查JWT过期的实用方法,这里给你唠唠靠谱的实现思路:
1. 用成熟JWT库自动验证(PHP实操首选)
别自己手动折腾解析,用像firebase/php-jwt这类常用库最安全省心,它会自动帮你处理过期校验,还能防篡改。举个简单的例子:
use Firebase\JWT\JWT; use Firebase\JWT\Key; function isJwtExpired(string $jwt, string $secret): bool { try { // 解析JWT时,库会自动验证签名+检查exp过期时间 $decoded = JWT::decode($jwt, new Key($secret, 'HS256')); return false; // 没过期返回false } catch (Firebase\JWT\ExpiredException $e) { return true; // 捕获到过期异常,说明JWT已失效 } catch (Exception $e) { // 其他异常:比如签名无效、JWT格式错误等,按业务需求处理 return true; // 也可以单独返回状态码区分不同异常 } }
这里要划重点:用官方维护的库比自己写逻辑安全多了,能避开很多你想不到的坑,比如时间戳格式、字符编码这些细节问题。
2. 手动解析(仅作了解,不推荐)
如果你好奇底层逻辑,也可以手动拆分JWT的Payload部分来检查:
function checkJwtExpiredManually(string $jwt): bool { $parts = explode('.', $jwt); if (count($parts) !== 3) { return true; // 格式不对,直接判定为无效/过期 } // 修复JWT的base64编码格式差异 $payloadJson = base64_decode(str_replace(['-', '_'], ['+', '/'], $parts[1])); $payload = json_decode($payloadJson, true); if (!isset($payload['exp'])) { // 没有exp字段的话,按业务规则处理:要么视为永不过期,要么直接判定无效 return false; } $currentTime = time(); return $payload['exp'] < $currentTime; }
但手动解析风险很高,比如容易忽略签名验证,万一JWT被篡改过也查不出来,所以强烈不推荐在生产环境这么用。
3. 业务层面的小技巧
我在项目里还会配合HttpOnly Cookie的逻辑优化体验:
- 用户请求需认证的接口时,后端先从HttpOnly Cookie里取出Access Token,用上面的方法校验是否过期
- 如果Access Token过期,就自动用Refresh Token生成新的Access Token,再存回HttpOnly Cookie里
- 要是Refresh Token也过期了,就引导用户重新登录
这样用户几乎感知不到过期刷新的过程,体验会顺畅很多。
内容来源于stack exchange
相关产品推荐
相关产品推荐

