Node应用使用node-oidc-provider实现登出自提交表单的CSP报错问题
问题原因
你遇到的CSP报错主要是以下两个常见原因导致的:
node-oidc-provider默认会在响应头中自动添加安全相关的CSP配置,你在页面meta标签中写的CSP不会覆盖响应头的CSP,反而会和响应头的规则叠加生效,需要同时满足两边的规则才能执行内联脚本,这是最核心的问题。- 你写在meta标签的CSP内容有大量换行和缩进,部分浏览器会解析异常,导致nonce规则没有被正确识别。
修复方案
步骤1:直接在Koa响应头设置CSP,不要使用meta标签配置
同时修正CSP规则,有nonce的情况下不需要加'unsafe-inline',浏览器会自动忽略该配置,不需要的话也可以去掉strict-dynamic减少兼容性问题。
步骤2:修改后的代码参考
async function getNonce () { const crypto = require("crypto"); // 生成base64url格式的nonce避免特殊字符解析问题 return crypto.randomBytes(16).toString("base64url"); } async function logoutSource (ctx, form) { const nonce = await getNonce(); // 直接设置响应头CSP,覆盖库默认的CSP配置 ctx.set('Content-Security-Policy', `script-src 'nonce-${nonce}'; default-src 'self'`); ctx.body = `<!DOCTYPE HTML> <head> <title>Logout</title> </head> <body> ${form} <script nonce="${nonce}"> var form = document.forms[0]; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'logout'; input.value = 'yes'; form.appendChild(input); form.submit(); </script> </body> </html>`; }
可选简化方案
如果不想处理nonce和CSP配置,也可以直接修改node-oidc-provider的登出交互配置,直接跳过确认页,具体可以在库的初始化配置中修改features.logoutSource的逻辑,不需要自行注入脚本。
内容的提问来源于stack exchange,提问作者Matti
相关产品推荐
相关产品推荐

