Safari浏览器中CSP指令'worker-src'未识别及Django嵌入Shopify故障排查
问题分析:Safari中Django Shopify嵌入应用CSP报错及500错误
问题描述
我有一个嵌入Shopify的Django应用,该应用在其他浏览器中运行正常,但在Safari浏览器中出现问题:日志提示'Unrecognized Content Security Policy directive 'worker-src'',且应用所有功能均返回内部服务器错误。以下是我settings.py中的CSP配置部分:
CSP_FRAME_ANCESTORS = ("'self'", 'https://*.myshopify.com') # default source as self CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'", "'unsafe-eval'", "https://fonts.gstatic.com") # style from our domain and bootstrapcdn CSP_STYLE_SRC = ("'self'", "'unsafe-inline'", "https://fonts.googleapis.com") # scripts from our domain and other domains CSP_SCRIPT_SRC = ("'self'", "'unsafe-inline'", "'unsafe-eval'") # images from our domain and other domains CSP_IMG_SRC = ("'self'", "https://*.s3.amazonaws.com", "data:", "https://cdn.shopify.com") SESSION_COOKIE_SAMESITE = 'None' SESSION_COOKIE_SECURE = True XS_SHARING_ALLOWED_METHODS = ['POST', 'GET', 'PUT'] CSRF_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SECURE = True STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') CSRF_TRUSTED_ORIGINS = [config('CSRF_TRUSTED_ORIGINS')]
问题原因
- 旧版Safari(14.0及以下)不支持
worker-src这个CSP指令,你的Django CSP依赖库会自动将该指令加入响应头,导致Safari解析CSP规则时失败,触发安全拦截,进而引发服务器内部错误。 SESSION_COOKIE_SAMESITE = 'None'和CSRF_COOKIE_SAMESITE = 'None'在旧版Safari中存在兼容性问题,可能导致Cookie无法正常传递,加剧功能异常。
解决方案
1. 兼容旧版Safari的CSP配置
如果使用django-csp库,显式配置worker-src或禁用自动生成:
# 显式设置worker-src,让旧版Safari可以识别,或回退到script-src规则 CSP_WORKER_SRC = ("'self'",) # 若不需要Web Worker功能,可直接设置为None避免自动生成该指令 # CSP_WORKER_SRC = None
确保所有CSP指令都是旧版Safari支持的语法,避免出现未识别指令。
2. 修复SameSite Cookie兼容性
针对旧版Safari调整SameSite Cookie配置,可通过自定义中间件实现动态适配:
from django.utils.deprecation import MiddlewareMixin class SafariSameSiteFixMiddleware(MiddlewareMixin): def process_response(self, request, response): user_agent = request.META.get('HTTP_USER_AGENT', '') # 检测旧版Safari(排除Chrome伪装的Safari) if 'Safari' in user_agent and 'Chrome' not in user_agent and ('Version/13' in user_agent or 'Version/14' in user_agent): if 'sessionid' in response.cookies: response.cookies['sessionid']['samesite'] = 'Lax' if 'csrftoken' in response.cookies: response.cookies['csrftoken']['samesite'] = 'Lax' return response
将该中间件加入settings.py的MIDDLEWARE列表中。若不想编写中间件,可暂时将SESSION_COOKIE_SAMESITE和CSRF_COOKIE_SAMESITE设为'Lax'测试,但需验证Shopify嵌入场景的功能是否正常。
3. 排查服务器详细错误
查看Django的django.request日志,获取内部服务器错误的具体异常信息,确认是CSP解析失败导致的请求中断,还是Cookie问题引发的认证/CSRF验证失败,针对性修复。
内容的提问来源于stack exchange,提问作者Sandeep KS
相关产品推荐
相关产品推荐

