Token身份验证在ThinkPHP5.0中分表单CSRF的\_token和API身份认证Token两类,后者需手动集成JWT等方案,通过中间件校验缓存/DB中的有效性、过期性及用户匹配。

Token身份验证的核心逻辑
ThinkPHP5.0中Token验证不是开箱即用的全局功能,而是按需启用的机制。它分两类场景:一类是表单防CSRF的_token(基于会话+路由+时间戳动态生成),另一类是API接口的身份认证Token(用于用户登录态维持)。两者命名、生成方式、存储位置和校验逻辑完全不同,不能混用。
API接口Token的典型实现流程
适用于App、小程序或前后端分离项目。关键步骤如下:
- 用户用账号密码(或微信code)请求登录接口,服务端验证通过后生成唯一Token
- Token可基于自定义算法(如
md5($uid . $time))、JWT或Lcobucci/JWT等标准方案 - 将Token与用户ID、过期时间存入数据库或缓存(如Redis/Cache::set)
- 返回
{token: "xxx", refresh_token: "yyy", expires_in: 3600}给客户端 - 后续请求在Header(如
Authorization: Bearer xxx)或参数中携带Token - 通过中间件统一校验:查缓存/DB是否存在该Token、是否过期、是否匹配用户
手动集成JWT Token的实用要点
比手写MD5更安全、易扩展。推荐使用lcobucci/jwt(ThinkPHP5兼容性好):
- 安装:
composer require lcobucci/jwt:^3.3 - 封装TokenService类,
createToken($uid)中设置issuedAt、expiresAt、with('uid', $uid) - 校验时捕获
ExpiredException和InvalidSignatureException,返回对应错误码 - 避免把敏感字段(如密码、手机号)直接塞进payload;仅放必要标识(uid、scope)
- 签名密钥(
key)必须严格保密,不硬编码在代码里,建议从配置文件或环境变量读取
常见问题与规避方法
开发中高频踩坑点:
立即学习“PHP免费学习笔记(深入)”;
- Token重复使用或被劫持:每次登录强制覆盖旧Token;refresh_token只允许使用一次,用后立即失效并清除
-
跨域请求带不上Token:前端需设置
credentials: 'include',后端CORS中间件开放Authorization头 -
缓存未及时更新:用户修改密码、登出时,主动删除对应缓存项(如
Cache::rm("token_{$uid}")) -
时间不同步导致JWT校验失败:服务端设
JWT::$leeway = 60,容忍1分钟偏差 -
调试时Token总报错:用Postman测试,先调登录接口复制返回的token,再在Headers里手动加
Authorization: Bearer xxx



















