直接写 CSP 响应头易覆盖 Laravel 默认安全头、难以动态控制 nonce/report-uri 且多中间件可能冲突;Spatie/laravel-csp 未生效需检查中间件注册位置、DEBUG 模式禁用及头覆写问题;内联脚本应优先用 nonce 或 hash 而非 unsafe_inline;connect-src 需单独配置外部 API;建议先用 Report-Only 模式收集日志再启用强制策略。
为什么直接写
响应头会出问题
手动在中间件或
里用
或
添加 CSP 头,容易覆盖 Laravel 自带的
、
等安全头,也难以动态控制内联脚本、nonce、report-uri 等复杂策略。更关键的是:Laravel 的响应生命周期中,多个中间件可能重复设置同名头,导致策略被截断或解析失败。
用
注册中间件后没生效?检查这三点
安装后运行
生成
配置文件
,但仅此不够:
确认
的
中已加入
(不是
middleware,否则 API
路由
也会被强制加头)
检查是否启用了
:该包默认在 debug 模式下禁用 CSP(避免开发时白屏),需显式设置
并在
中设
确认没有其他中间件(如自定义安全头中间件、CDN 缓存中间件)在
之后又覆写了
头
配置里
和
怎么选
允许内联脚本最常见需求是 Vue/Alpine 的
或 Blade 中的
,但
是高危选项,应优先用 nonce 或 hash:
Comet AI 浏览器
下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。
下载
启用 nonce:在
中设
→ 不安全;正确做法是删掉
,改用
'],并在 Blade 模板中给
加上
属性
用 hash 替代:对已知内联脚本内容做 SHA256,例如
对应
,填入
;但每次修改脚本都要重算 hash,适合静态片段
第三方 JS(如 Google Analytics)必须显式添加域名:
,不能只写
(协议和端口必须匹配)
如何让 CSP 允许
请求到外部 API(比如 Stripe)
CSP 的
控制
、
、
等连接行为,和
是分开的:
注意:
不继承
的值;如果漏配,
浏览器
控制台会报
;另外,
开发环境需单独加上
(协议不能省)。
CSP 的
和
在现代浏览器中行为不一致,且上报 endpoint 需要能接收 POST JSON 并防滥用,实际项目中建议先用
头跑一周收集违规日志,再切到 enforce 模式——这点很容易被跳过。
Content-Security-PolicyApp\Http\Kernelheader()response()->withHeaders()X-Frame-OptionsX-Content-Type-OptionsSpatie/laravel-cspphp artisan vendor:publish --provider="Spatie\Csp\CspServiceProvider"config/csp.phpapp/Http/Kernel.php$middlewareGroups['web']\Spatie\Csp\AddCspHeaders::classglobalAPP_DEBUG=true'enabled' => env('CSP_ENABLED', true).envCSP_ENABLED=trueAddCspHeadersContent-Security-Policycsp.php'scripts' => []'unsafe_inline'@click@stack('scripts')unsafe_inlineconfig/csp.php'scripts' => ['self', 'unsafe_inline']unsafe_inline'scripts' => ['self', 'nonce-{{ csp_nonce() }}nonce'sha256-abc123...''scripts' => ['self', 'sha256-abc123...']'scripts' => ['self', 'https://www.googletagmanager.com']googletagmanager.comfetch()connect-srcfetchXMLHttpRequestEventSourcescript-srcreturn [
'connect-src' => [
'self',
'https://api.stripe.com',
'https://hooks.stripe.com',
],
];connect-srcscript-srcRefused to connect to 'https://api.stripe.com' because it violates the following Content Security Policy directivelocalhost'http://localhost:8000'report-urireport-toContent-Security-Policy-Report-Only