ThinkPHP防CSRF需启用全局配置、嵌入令牌、配置AJAX头、手动绑定中间件并验证生效:修改config/app.php设'app_csrf_state'=>true,表单插入{:token()},AJAX通过meta标签读取并传X-CSRF-TOKEN头,路由可单独加token中间件,最后用无令牌请求测试返回403确认防护生效。

如果您在ThinkPHP项目中需要防止跨站请求伪造攻击,但当前表单提交未受令牌校验保护,则说明CSRF验证机制尚未启用。以下是开启CSRF验证的具体方法:
一、启用全局CSRF配置
ThinkPHP通过配置项控制CSRF中间件的启用状态,该配置直接影响所有POST、PUT、DELETE等非安全方法的请求拦截行为。需确保应用处于调试关闭或生产环境,并修改核心配置文件。
1、打开项目根目录下的 config/app.php 文件。
2、查找 app_csrf_state 配置项,将其值设为 true。
立即学习“PHP免费学习笔记(深入)”;
3、若该配置项被注释,请取消注释;若不存在,手动添加到返回数组中,格式为:'app_csrf_state' => true。
4、保存文件后,执行 php think route:clear 清除路由缓存。
二、在表单中嵌入CSRF令牌
启用全局验证后,所有POST表单必须携带有效令牌,否则请求将被中间件拒绝。框架提供内置函数生成与当前会话绑定的一次性令牌。
1、在HTML表单内部、<form> 标签内任意位置插入:<input type="hidden" name="__token__" value="{:token()}">。
2、若使用模板引擎(如ThinkTemplate),直接写入 {:token()} 即可渲染令牌值。
3、确保该隐藏字段名称为 __token__,且未被JavaScript动态移除或覆盖。
三、为AJAX请求配置CSRF头
前端通过XMLHttpRequest或fetch发起POST请求时,无法自动提交表单隐藏域,需显式传递令牌至服务端。服务端通过X-CSRF-TOKEN请求头识别并校验。
1、在页面HTML的 <head> 区域添加meta标签:<meta name="csrf-token" content="{:token()}">。
2、JavaScript中读取该meta值:const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');。
3、发起AJAX请求时,在请求头中加入:headers: { 'X-CSRF-TOKEN': token }。
四、手动注入令牌至特定路由
当部分接口需独立启用CSRF防护(如仅对/api/submit路径生效),可绕过全局配置,直接在路由定义中绑定ValidateToken中间件。
1、打开路由定义文件(如 route/app.php)。
2、为指定路由添加中间件链,例如:Route::post('api/submit', 'Api/Submit/save')->middleware('token');。
3、确认 think\middleware\ValidateToken::class 已注册于中间件管道中。
4、该路由下所有匹配请求将强制校验令牌,无论全局配置状态如何。
五、验证CSRF是否生效
完成配置后需进行有效性测试,避免因缓存、路径匹配或中间件顺序导致防护失效。
1、构造一个不含令牌的POST请求(如curl -X POST http://yourdomain.com/index/user/login)。
2、观察响应状态码:正常应返回 403 Forbidden 或被路由层误判为 404 Not Found(见中间件拦截逻辑)。
3、在浏览器开发者工具Network面板中,检查目标请求的Headers是否包含 X-CSRF-TOKEN 字段及其值是否与页面meta中一致。
4、提交含正确令牌的表单,确认控制器方法可正常执行且无异常抛出。



















