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

时间:2013-05-17 01:18:19

标签: 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
....

我该怎么办?

7 个答案:

答案 0 :(得分:14)

如果有人仍然关注这个问题,直接的答案是你需要在view方法本身上使用装饰器。 get类上定义的postAPIView方法只告诉DRF实际视图应该如何运行,但django路由器期望的视图方法实际上不会实例化,直到您调用{{ 1}}。

因此,解决方案是将LoginView.as_view()装饰器添加到csrf_exempt。它可能如下所示:

urls.py

但是,正如Mark上面指出的那样,csrf保护对于防止会话被劫持很重要。我自己没有使用iOS,但我会考虑使用django的cookie-based csrf tokens。您可以使用#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())), ... ) 装饰器使django发送带有响应的ensure_csrf_cookie Cookie,只要您将该标记包含为csrftoken标头,您的POST请求就会生效

答案 1 :(得分:3)

您遇到的问题是用于处理视图的django使用的是as_view()方法将返回的内容,而不是直接方法get()post()

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

  1. 在urls.py
  2.     urlpatterns = patterns('',
            url('^login/$', csrf_exempt(views.LoginView.as_view())),
            ...
        )
    
    1. dispatch()方法(pre django 1.9)
    2.     from django.utils.decorators import method_decorator
      
          class LoginView(APIView):
             @method_decorator(csrf_exempt)
             def dispatch(self, *args, **kwargs):
                 ...
      
      1. 或类视图本身(来自django 1.9)
      2.     from django.utils.decorators import method_decorator
        
        
            @method_decorator(csrf_exempt, name='dispatch')
            class LoginView(APIView):
                   ...
        

答案 2 :(得分:2)

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

如果您使用POST修改数据,那么如果您使用基于会话的身份验证,则应该有CSRF。否则,你正在打开一个安全漏洞。即使您认为您的Django服务器将要为iPhone应用程序提供服务,但没有什么可以阻止您的应用程序嗅探流量到服务器的数据包,然后使用其他类型的Web客户端逆向工程访问服务器。因此,Django Rest Framework在某些情况下需要CSRF。这在Django rest framework documentation中提到。

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

答案 3 :(得分:2)

我有同样的问题。我的问题是我忘记将.as_view()放在MyAPIView的urls.py中。所以它必须像:

url(r'$', GetLikesAPI.as_view(), name='list')

不是:

url(r'$', GetLikesAPI, name='list')

答案 4 :(得分:1)

在我的情况下,它发生了,因为我发送了请求到url =' http://example.com/list/5'最后没有斜线。当我将网址更改为url =' http://example.com/list/5/'一切都开始奏效了。

答案 5 :(得分:0)

这是一个老问题,但我们最近遇到了一些问题。

除非使用会话身份验证,否则DRF会默认禁用CSRF。默认情况下,NSURLconnection设置为处理cookie。您需要明确告诉iOS应用不使用cookie。然后,如果需要,您可以继续使用会话身份验证,而不必让csrf免除您的观点。

答案 6 :(得分:0)

urlpatterns = patterns('',
       url('^login/$', csrf_exempt(views.LoginView.as_view())),
       ...
)

专家。我有同样的错误,花了很多时间才发现: 1)我有另一个'登录'的路由器,我错过了'$'。我的意思是有时候你会忘记路由中的某些内容并得到这个错误。