我有两个独立的后端,都是用 Django 构建的,我想相互通信。对
GET
端点的请求工作正常,但 POST
请求给了我以下错误:
Forbidden (CSRF cookie not set.): /endpoint/path/
Django 的说明提到了“任何使用 POST 表单的模板”中的设置
{% csrf_token %}
。但我没有模板!这只是一个 API。
如何解决此错误?
一个“解决方案”是从您的
"django.middleware.csrf.CsrfViewMiddleware"
中删除 settings.py
中间件,但不建议这样做。
实际上还有另一种方法可以将 csrf 令牌传递到 API 响应,而不需要 POST 表单。由于某种原因,Django 文档没有这方面的示例。只需拨打
django.middleware.csrf.get_token()
即可。这是一个例子。
# In a views.py
from django import http
from django.middleware.csrf import get_token
...
@http.require_safe
@cache.never_cache
def get_csrf(request):
# This call will automatically add the token to the response!
get_token(request)
return http.HttpResponse("hello world")
@http.require_POST
@cache.never_cache
def post_data(request):
msg = "received POST request"
return http.HttpResponse(msg)
# Also in a views.py
import requests
...
URL = "https://url.to.server/"
def update_session(session, response):
response.raise_for_status()
session.cookies.update(response.cookies)
session.headers["x-csrftoken"] = response.cookies["csrftoken"]
@http.require_GET
@cache.never_cache
def test_api(request):
# You will want to create a session and store the cookie so it can be easily reused
session = requests.Session()
csrf_response = session.get(f"{URL}get_csrf/")
update_session(session, csrf_response)
# The previously problematic POST request should now work
response = session.post(f"{URL}post_data/")
# `response.text` should now successfully contain "received POST request"
return http.HttpResponse(response.text)