启用内容安全策略(CSP)后Facebook Login JavaScript SDK失效,求排查
我仔细看了你给出的CSP配置和遇到的问题——Facebook登录在禁用CSP时正常,启用后就失效,这大概率是CSP规则遗漏了Facebook登录必需的资源权限。下面是具体的修正点和完整配置建议:
1. 修正connect-src规则
你的connect-src只允许了'self',但Facebook登录过程中需要向Graph API、Facebook验证服务器发起请求来完成身份校验、获取用户信息,这些请求都会被当前的CSP拦截。需要补充相关域名:
connect-src 'self' https://graph.facebook.com https://www.facebook.com;
2. 补充style-src规则
你当前的CSP没有定义style-src,会默认继承default-src 'none',但Facebook的登录按钮会加载内联样式或者外部样式资源,这会被CSP直接阻止。建议添加:
style-src 'self' 'unsafe-inline' https://staticxx.facebook.com;
如果不想用'unsafe-inline'(更安全的做法),可以打开浏览器控制台,找到被拦截的内联样式的哈希值,把哈希值添加到style-src里代替'unsafe-inline'——不过Facebook的动态样式可能会变化,'unsafe-inline'是最省心的临时方案。
3. 调整script-src规则
虽然你已经包含了https://connect.facebook.net(Facebook SDK的核心地址),但SDK运行时会生成内联脚本,这些脚本会被当前的CSP拦截。需要允许内联脚本,或者添加对应的nonce/哈希值。如果暂时不想修改代码添加nonce,可以先加上'unsafe-inline':
script-src 'self' 'unsafe-inline' https://code.jquery.com https://connect.facebook.net;
另外,https://graph.facebook.com是API请求地址,不属于脚本资源,应该移到connect-src里,所以可以从script-src中移除。
4. 优化frame-src规则
你当前的frame-src配置基本没问题,但可以统一使用HTTPS地址(现在Facebook的资源都默认走HTTPS了),去掉HTTP的http://staticxx.facebook.com:
frame-src https://www.facebook.com https://staticxx.facebook.com;
完整的修正后CSP配置
default-src 'none'; connect-src 'self' https://graph.facebook.com https://www.facebook.com; frame-src https://www.facebook.com https://staticxx.facebook.com; img-src 'self' https://*.facebook.com https://scontent.xx.fbcdn.net; script-src 'self' 'unsafe-inline' https://code.jquery.com https://connect.facebook.net; style-src 'self' 'unsafe-inline' https://staticxx.facebook.com;
这样调整后,Facebook登录需要的脚本加载、API通信、iframe嵌入、样式渲染都能被CSP允许,应该就能正常工作了。如果还是有问题,可以打开浏览器的开发者工具,查看控制台里的CSP拦截报错,根据报错信息补充对应的规则即可。
内容的提问来源于stack exchange,提问作者Frumentius

