如何为两个 Django 应用程序之间的纯 REST API 通信设置 CSRF 令牌?

问题描述 投票:0回答:1

我有两个独立的后端,都是用 Django 构建的,我想相互通信。对

GET
端点的请求工作正常,但
POST
请求给了我以下错误:

Forbidden (CSRF cookie not set.): /endpoint/path/

Django 的说明提到了“任何使用 POST 表单的模板”中的设置

{% csrf_token %}
。但我没有模板!这只是一个 API。

如何解决此错误?

django post http-status-code-403 django-csrf
1个回答
0
投票

一个“解决方案”是从您的

"django.middleware.csrf.CsrfViewMiddleware"
中删除
settings.py
中间件,但不建议这样做。

实际上还有另一种方法可以将 csrf 令牌传递到 API 响应,而不需要 POST 表单。由于某种原因,Django 文档没有这方面的示例。只需拨打

django.middleware.csrf.get_token()
即可。这是一个例子。

服务器 1 - 需要 csrf 令牌(“服务器”)

# 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)

服务器 2 - 发出请求(“客户端”)

# 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)
© www.soinside.com 2019 - 2024. All rights reserved.