【发布时间】: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 项目相关的问题
- 'request.data' empty when multipart form data POST in 3.3.x 3814
- Request.data empty when multipart/form-data POSTed 3951
编辑 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