【问题标题】:DRF asking for CSRF Token with TokenAuthentication as the only auth methodDRF 要求使用 TokenAuthentication 作为唯一身份验证方法的 CSRF 令牌
【发布时间】:2020-11-04 02:09:12
【问题描述】:

我唯一的 DRF 身份验证系统是 TokenAuthentication,它仍然在基于函数的视图上请求 CSRF 令牌。我对基于类的视图没有这个问题。

settings.py:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication'
    ]
}

views.py:

@api_view(['POST'])
@authentication_classes([TokenAuthentication])
def submit_vote(request):
    # ...

在 Postman 的 POST 请求中:

Forbidden (CSRF cookie not set.): /rest/submit_vote/
[04/Nov/2020 02:05:38] "POST /rest/submit_vote/ HTTP/1.1" 403 2864

什么?!

我没有任何待处理的迁移。

【问题讨论】:

  • csrf 和 auth 不一样。
  • 然后呢? DRF 文档:“如果您使用 SessionAuthentication,则需要为任何 POST、PUT、PATCH 或 DELETE 操作包含有效的 CSRF 令牌。”,我没有使用 SessionAuthentication。
  • DRF 不会给你一个 CSRF 令牌丢失异常,除非你覆盖它的东西。最好检查您的 URL,以便您可能请求其他视图。

标签: python django django-rest-framework


【解决方案1】:

仅当使用SessionAuthentication 时,才在 DRF 中启用 CSRF。用户需要使用 session 登录,才能强制 DRF 检查 CSRF。

如果您使用TokenAuthentication,DRF 将不会向客户端发送 CSRF,也不会在响应中的 cookie 中要求 CSRF。

如果您有Forbidden (CSRF cookie not set.),那么您的代码/浏览器可能存在问题:

  • 请仔细检查您的任何视图中是否没有使用csrf_token 标签,如果您有这样的视图,它将强制 Django 向您发送 CSRF cookie
  • 请仔细检查您的 cookie 中没有 CSRF 令牌(只需清除所有 cookie),搜索 X-CSRFToken
  • 请检查服务器响应头的样子,是否有 CSRF cookie?它不应该在那里,
  • 请检查您的请求标头的外观,您是否在标头中发送任何 cookie?

如果您仍然有问题,请提供一个最小的工作示例来重现此行为,我会帮助您。

【讨论】:

    【解决方案2】:

    任何 POST、PUT、PATCH 或 DELETE 或 Django 中的请求都需要 CSRF 令牌。如果您使用 Postman 发送请求,check this Medium post to see how to set the CSRF token in Postman

    您还可以通过添加 csrf_exempt 装饰器来禁用 csrf_token 验证。 不推荐。

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    def my_view(request):
        return HttpResponse('Hello world')
    

    【讨论】:

    • 为什么我对基于类的视图的 CSRF 令牌没有任何问题?我确实使用了 POST 和 DELETE。
    • DRF 在幕后应用 csrf_exempt 装饰器。此外,这是裸 Django 视图,无法处理 DRF 权限和身份验证类
    • @GonzaloDambra,希望这个答案对您有所帮助。如果确实如此,请接受并投票:)。至于你的问题,Arrakal 是对的,如果你不使用 SessionAuthentication,DRF 会在幕后应用 csrf_exempt 装饰器。
    猜你喜欢
    • 2017-06-05
    • 2018-06-22
    • 1970-01-01
    • 2020-09-12
    • 2018-01-26
    • 2017-01-01
    • 1970-01-01
    • 2014-08-17
    • 2016-10-08
    相关资源
    最近更新 更多