应启用全局CSRF配置、控制器中间件、路由级保护、手动校验及令牌刷新:一、在config/app.php中设'form_token'=>true并配置salt与ttl;二、控制器声明TokenCheck中间件;三、路由添加'token'=>true选项;四、方法内调用$this->request->token();五、渲染前用TokenService::reset()刷新令牌。

如果您在ThinkPHP项目中发现表单提交频繁触发“非法请求”提示,或用户在多标签页操作时令牌校验失败,则可能是CSRF防护未正确配置或存在校验逻辑断点。以下是解决此问题的步骤:
一、启用全局CSRF令牌配置
通过修改核心配置文件激活框架级令牌生成与校验机制,确保所有受保护路由默认参与验证流程。
1、打开项目根目录下的config/app.php文件。
2、在配置数组中添加或确认以下键值对已存在且值为true:
立即学习“PHP免费学习笔记(深入)”;
'form_token' => true,
3、同时设置盐值与有效期以增强令牌唯一性与时效性:
'token_salt' => 'your_custom_salt_here',
'token_ttl' => 3600,
二、在控制器中启用令牌校验中间件
绕过全局配置限制,针对特定控制器或方法精准控制CSRF防护粒度,避免误拦截非敏感接口。
1、在目标控制器类顶部声明中间件数组:
protected $middleware = [\think\middleware\TokenCheck::class];
2、若使用ThinkPHP 8,可改用更明确的中间件路径:
protected $middleware = [\think\middleware\FormTokenCheck::class];
3、确保该控制器继承\think\Controller或其子类,以支持中间件自动注入。
三、在路由定义中显式开启令牌保护
将CSRF防护绑定至具体路由规则,实现接口级策略控制,适用于API模块或混合请求类型场景。
1、打开route/app.php文件。
2、在定义POST或状态变更型路由时,附加'token' => true选项:
Route::post('user/update', 'UserController@update')->option(['token' => true]);
3、若为批量路由注册,可在分组中统一设置:
Route::group(['token' => true], function () { Route::post('profile/save', 'ProfileController@save'); });
四、手动调用令牌校验方法
在不依赖中间件的轻量控制器中,通过代码主动触发校验逻辑,适用于需动态判断是否启用防护的业务分支。
1、在控制器方法开头调用$this->request->token():
$this->request->token();
2、若需指定字段名(如兼容旧前端),传入自定义参数:
$this->request->token('__csrf_token');
3、该调用会立即执行验证,失败时抛出ValidateException并中断执行。
五、强制刷新失效令牌以支持页面重试
解决因浏览器缓存、URL参数变化或多标签页导致的令牌不一致问题,确保用户刷新页面后仍能正常提交。
1、在控制器渲染表单前,调用令牌服务重置方法:
\think\Service\TokenService::reset();
2、若使用ThinkPHP 6.1+,可改用构建式刷新:
\think\Service\TokenService::buildToken(true);
3、模板中继续使用{:token()},其将自动读取最新生成的令牌值。



















