核心问题是校验逻辑与数据传递方式错配:thinkphp默认从post表单取__token__,而前后端分离多用json提交、无表单dom、跨域请求,导致token未传或传错位置;需后端提供/api/token接口返回token值,前端将其写入json body,禁用全局token中间件并按需启用,同时确保session跨域有效。

前后端分离场景下,ThinkPHP 的 Token 验证失败,核心问题不是“没校验”,而是「校验逻辑和数据传递方式错配」——框架默认从 POST 表单中取 __token__,而前后端分离通常用 JSON 提交、无表单 DOM、甚至跨域请求,导致 Token 根本没传过去或传错位置。
确认 Token 是否被正确生成并暴露给前端
ThinkPHP 的令牌依赖 Session 生成,且需显式输出。前后端分离时,后端不能靠模板标签 {:token()} 渲染,必须主动提供接口返回有效 Token 值。
- 新增一个轻量接口(如
/api/token),在控制器中调用\think\facade\Form::token()(V6.1+)或Token::build()(V5.x),返回纯字符串值 - 确保该接口不启用 Token 中间件(否则形成死锁),也不受 CSRF 或登录中间件拦截
- 响应头设为
Content-Type: application/json,避免框架自动包装成视图
前端提交时必须把 Token 放进请求体,而非 headers 或 URL
ThinkPHP 默认只从 $_POST 或请求体中的表单字段解析 __token__,不会从请求头(如 X-CSRF-TOKEN)读取,也不支持 GET 参数校验。
- 若用
application/json提交,需将 Token 显式写入 JSON body:{"title":"xxx","__token__":"abc123..."} - 若用
application/x-www-form-urlencoded,确保 FormData 实例已包含__token__字段(不能只靠 JS 取 DOM,因无表单 DOM) - 禁止把 Token 放在 headers 里——框架不识别,校验直接跳过或报错
后端需关闭全局 Token 校验,按需启用
前后端分离项目中,多数 API 接口(如列表、详情、上传)并不需要 Token 防护;若在中间件中全局开启 token,会导致所有 POST 接口强制校验,而这些接口根本没传 __token__。
- 在路由定义中精准控制:对提交类接口(如
POST /api/article/save)显式附加中间件token - 或在控制器构造方法中:
$this->middleware('token')->only(['save', 'edit']); - 避免在
app/middleware.php中全局注册token中间件
检查 Session 有效性与跨域兼容性
Token 值存在 Session 中,前后端分离常伴随跨域,若 Cookie 未携带或 Session ID 丢失,服务端无法匹配原始 Token。
- 前端请求需设置
credentials: 'include'(fetch)或withCredentials: true(axios) - 后端响应头必须包含:
Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能为*,须指定具体域名 - 确认 Session 配置正常:
'type' => 'file'时检查临时目录可写;用 Redis 时确认连接畅通
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











