【问题标题】:Django DRF CSRF token missing - DRF deleted request.POST data?Django DRF CSRF 令牌丢失 - DRF 删除了 request.POST 数据?
【发布时间】:2017-07-24 03:04:48
【问题描述】:

我正在使用 Django Rest 的可浏览 API 来使用会话身份验证进行 POST,并且我正在丢失 CSRF 令牌,即使它已提供。我正在寻求有关配置我的 ModelViewSet 子类的建议,以便它工作。

这是我的观点:

class TreeAPI(ModelViewSet):
    authentication_classes = (SessionAuthentication,)
    queryset = Tree.objects.get_roots()
    parser_classes = (JSONParser, FormParser, MultiPartParser)
    permission_classes = (IsAdminUser,)
    throttle_classes = (TreeThrottle,)
    serializer_class = TreeSerializer

我可以使用 DRF Browsable API 到 GET 这个端点,但是当我用它到 POST 这个端点时,我得到一个带有消息 CSRF token missing or incorrect 的 403。

当我在the constructor to rest_framework.request.Request设置断点时,可以看到传入的请求包含了需要的csrfmiddleware令牌:

在 Django Rest 的 Request 类中,POST 实际上是一个属性:

@property
def POST(self):
    if not _hasattr(self, '_data'):
        self._load_data_and_files()
    if is_form_media_type(self.content_type):
        # self.data is an empty QueryDict!
        return self.data
    return QueryDict('', encoding=self._request._encoding)

request.POST 不再包含csrfmiddlewaretoken 键;它被剥夺了表单提供的所有键:

因此,传递给rest_framework.authentication.SessionAuthentication.enforce_csrf(request) 的参数然后传递给django.middleware.csrf.CsrfViewMiddleware.process_view 找不到csrfmiddlewaretoken 令牌:

        if request.method == "POST":
            request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')

我可以检查什么?这里有哪些可能的错误来源?

注意事项

  • 对禁用 CSRF 不感兴趣
  • 对使用令牌身份验证不感兴趣
  • 熟悉如何使用 CSRF 令牌及其上的 Django 文档
  • 熟悉Django REST's docs on CSRF tokens
  • 这是内置的 Django REST 可浏览 API;没有修改 UI 中的任何内容

编辑 1 - 中间件

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

EDIT 2 - 软件版本 - djangorestframework==3.3.3 - Django==1.9.8

EDIT 3 - 可能与 git 项目相关的问题

编辑 4 - 可能相关的堆栈溢出帖子
- Having a POST'able API and Django's CSRF Middleware
- How to make a POST simple JSON using Django REST Framework? CSRF token missing or incorrect
- How to make a Django-Rest-Framework API that takes POST data?
- Django Rest Framework, ajax POST works but PATCH throws CSRF Failed: CSRF token missing or incorrect
- http://www.django-rest-framework.org/api-guide/parsers/#formparser

【问题讨论】:

  • 这很奇怪。你的中间件设置是什么?也许那里也缺少一些东西。
  • @Linovia,我不认为是这样,因为我已经验证了 CSRF cookie 发送正确。无论如何,看看 2017-03-06 的编辑。
  • 你能用 postman 或 curl 做请求吗?您是否以任何方式自定义了视图集?另外,为什么要使用所有三个解析器?

标签: django django-rest-framework csrf-protection


【解决方案1】:

djangorestframework==3.5.4 中没有出现此问题。见http://www.django-rest-framework.org/topics/release-notes/;我感觉这在 3.3.x 之后得到了修复。

【讨论】:

    猜你喜欢
    • 2019-10-08
    • 2015-12-12
    • 2017-10-29
    • 2018-09-07
    • 1970-01-01
    • 2016-10-11
    • 2021-07-14
    • 2020-01-05
    • 1970-01-01
    相关资源
    最近更新 更多