我们创建了一个 Django 应用程序来创建 Shopify 应用程序。我们在生产环境中遇到问题,我们对 Django 应用程序的 AJAX 调用失败,因为 CSRF 令牌没有保存到 cookie,因此 AJAX 调用标头中没有解析任何内容。
我们遵循 Django 文档,并在所有其他 html 文件引用的
{% csrf_token %}
文件的 <head>
标签中添加了 base.html
。我还尝试将以下内容添加到 <head>
标签中:
<script>
var csrf_token = '{{ csrf_token }}';
</script>
我的 AJAX 调用如下所示:
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
method: 'POST',
headers: {
'X-CSRFToken': csrf_token,
'X-Shopify-Domain': shopifyDomain
},
mode: 'same-origin',
success: function(data) {
resolve(data);
},
error: function(xhr, status, error) {
console.error(`Error in ${url}:\nStatus: ${xhr.status}\nError: ${error}\nResponse: ${xhr.responseText}`);
reject(new Error(`Error in ${url}: ${xhr.responseText}`));
}
});
因为这是一个 Shopify 应用程序,所以该应用程序嵌入到 Shopify 中的 iFrame 中,但我不确定这是罪魁祸首,因为它在我们的开发环境中是相同的。生产应用程序位于 Azure 应用服务并位于 Azure 前门后面,不确定这是否会导致任何问题。
浏览器中似乎确实有来自我们域的 cookie,只是没有 csrf 令牌:
我们找不到解决方案来解释为什么会发生这种情况。我们必须用
@csrf_exempt
标记我们的函数调度,我们不想继续这样做。例如:
@csrf_exempt
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
鉴于您的请求来自不同的来源(通过 iframe 进行 Shopify),您必须在 settings.py 中设置各种标志,例如“同一站点”和“csrf 可信来源”标志。它将允许根据来自不同来源的请求发送 cookie (https://code.djangoproject.com/ticket/27863)
尝试将这些添加到您的 django 设置中。
SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None