Django REST框架CSRF失败:未设置CSRF cookie

use*_*822 20 python django django-views django-rest-framework

我正在使用django rest框架通过IOS执行API调用,我收到以下错误"CSRF失败:未设置CSRF cookie".

这是我的django API代码:

class LoginView(APIView):
    """
    List all snippets, or create a new snippet.
    """
    @csrf_exempt
    def get(self, request, format=None):
        startups = Startup.objects.all()
        serializer = StartupSerializer(startups, many=True)
        return Response(serializer.data)

    @csrf_exempt
    def post(self, request, format=None):
        profile = request.POST
....
Run Code Online (Sandbox Code Playgroud)

我能做什么?

Rah*_*aki 14

如果有人仍在关注这个问题,那么直接的答案就是你需要在view方法本身上使用装饰器.在类上定义的getpost方法APIView只是告诉DRF实际视图应该如何表现,但django路由器期望的视图方法在您调用之前实际上并未实例化LoginView.as_view().

因此,解决方案是添加csrf_exempt装饰器urls.py.它可能如下所示:

#file: urls.py

from django.conf.urls import patterns, url
from django.views.decorators.csrf import csrf_exempt

import views

urlpatterns = patterns('',
    url('^login/$', csrf_exempt(views.LoginView.as_view())),
    ...
)
Run Code Online (Sandbox Code Playgroud)

但是,正如Mark上面指出的那样,csrf保护对于防止会话被劫持很重要.我自己没有使用iOS,但我会考虑使用django 基于cookie的csrf令牌.您可以使用ensure_csrf_cookie装饰器使django发送csrftoken带响应的cookie,POST只要您将该标记包含在X-CSRFToken标题中,您的请求就会生效.


М.Б*_*.Б. 9

我有同样的问题。我的问题是我忘了把.as_view()urls.py 放在MyAPIView. 所以它必须是这样的:

url(r'$', GetLikesAPI.as_view(), name='list')
Run Code Online (Sandbox Code Playgroud)

不是:

url(r'$', GetLikesAPI, name='list')
Run Code Online (Sandbox Code Playgroud)

  • 这种情况不太可能发生,因为如果您错过了“as_view()”,则该路线可能完全无法访问。 (3认同)

the*_*edk 5

您在这里遇到的问题是用于处理您的视图的 django 正在使用as_view()将返回的任何方法,而不是直接使用方法get()post().

因此,您应该通过以下方式之一装饰基于类的视图:

  1. 在 urls.py 中
    urlpatterns = 模式('',
        url('^login/$', csrf_exempt(views.LoginView.as_view())),
        ...
    )
  1. 或 ondispatch()方法(django 1.9 之前)
    从 django.utils.decorators 导入 method_decorator

    类登录视图(APIView):
       @method_decorator(csrf_exempt)
       def dispatch(self, *args, **kwargs):
           ...
  1. 或在类视图本身(来自 django 1.9)
    从 django.utils.decorators 导入 method_decorator


    @method_decorator(csrf_exempt, name='dispatch')
    类登录视图(APIView):
           ...


Mar*_*ian 4

对于 GET,您不应修改数据,因此不需要 CSRF。

如果您使用 POST 修改数据,并且使用基于会话的身份验证,则应该有 CSRF。否则,你就会打开一个安全漏洞。即使您认为 Django 服务器将为 iPhone 应用程序提供服务,也无法阻止使用您的应用程序的人嗅探到您服务器的流量数据包,然后使用其他类型的 Web 客户端对服务器进行反向工程访问。因此,Django Rest Framework 在某些情况下需要 CSRF。Django Rest 框架文档中提到了这一点。

解决 POST 要求的方法是不使用会话身份验证。例如,您可以通过 HTTPS 使用 BasicAuthentication。使用此身份验证机制,您应该使用 HTTPS 来防止每个请求都以明文方式传递凭据。