ThinkPHP 8.0 安全请求头校验需通过中间件统一实现:一校验 Referer 防 CSRF,二校验 X-Requested-With 防非 AJAX 提交,三校验 X-Request-ID 防重放,四配合 CSP 中间件设置 Content-Security-Policy 响应头。

一、校验 Referer 防 CSRF 和恶意调用
对敏感操作(如删除、支付、配置修改)可限制请求来源域名,避免被第三方页面诱导提交。
- 在中间件中读取 $request->header('referer'),提取协议+域名(如
https://admin.example.com) - 与白名单数组比对:
$allowedReferers = ['https://admin.example.com', 'http://localhost:8080'] - 不匹配则直接返回 403:
return response('Forbidden', 403); - 注意:Referer 可被客户端伪造,仅作辅助防护,不能替代 CSRF Token
二、校验 X-Requested-With 防非 AJAX 提交
很多老项目依赖该头判断是否为 AJAX 请求,虽非绝对安全,但可快速拦截部分表单直刷行为。
- 检查是否为
X-Requested-With: XMLHttpRequest - 若接口只接受 AJAX 调用,可强制校验:
if (!$request->header('x-requested-with') || strtolower($request->header('x-requested-with')) !== 'xmlhttprequest') { abort(400, 'Invalid request type'); } - 注意:现代前端(如 Fetch API)默认不带此头,需手动设置;Vue/React 项目建议统一加,再在此处校验
三、校验 X-Request-ID 或自定义防重放头
用于识别重复请求、追踪链路、配合幂等性控制。服务端生成或校验该头,确保每次请求唯一且可信。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 前端需在请求头中带上
X-Request-ID: [uuid](如使用 uuidv4) - 后端中间件中校验格式:
if (!is_string($rid) || !preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $rid)) { abort(400, 'Invalid X-Request-ID'); } - 进阶可结合 Redis 缓存该 ID + 时间戳(如 5 分钟有效期),实现简单防重放
四、校验 Content-Security-Policy 相关头(配合 CSP 中间件)
不是校验请求头,而是主动设置响应头,并要求前端脚本遵守 nonce 约束——这是浏览器端最后一道防线。
立即学习“PHP免费学习笔记(深入)”;
- 写一个
CspMiddleware,在handle()中生成随机 nonce:$nonce = base64_encode(random_bytes(16)); - 注入响应头:
$response->header('Content-Security-Policy', "script-src 'self' 'nonce-{$nonce}'"); - 同时把
$nonce传给模板:$this->view->assign('nonce', $nonce) - 前端内联脚本必须带
nonce="{$nonce}",否则被浏览器拦截


















