2017-07-02 111 views
0

我有这种说法Django的REST框架故宫CSRF的cookie没有设置

from rest_framework import parsers, renderers 
from rest_framework.authtoken.models import Token 
from rest_framework.authtoken.serializers import AuthTokenSerializer 
from rest_framework.response import Response 
from rest_framework.views import APIView 
from .serializers import EmailUserSerializer 
from django.utils.decorators import method_decorator 
from django.views.decorators.csrf import csrf_exempt 


@method_decorator(csrf_exempt, name='post') 
class ObtainAuthToken(APIView): 
    throttle_classes =() 
    permission_classes =() 
    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) 
    renderer_classes = (renderers.JSONRenderer,) 
    serializer_class = AuthTokenSerializer 

    def post(self, request, *args, **kwargs): 
     serializer = self.serializer_class(data=request.data) 
     serializer.is_valid(raise_exception=True) 
     user = serializer.validated_data['user'] 
     token, created = Token.objects.get_or_create(user=user) 
     user_serializer = EmailUserSerializer(user) 
     return Response({'token': token.key, 'user': user_serializer.data}) 


obtain_auth_token = ObtainAuthToken.as_view() 

这个网址

urlpatterns = [ 
    url(r'^login/$',views.obtain_auth_token, name='get_auth_token'), 
    url(r'^login2/$',ObtainAuthToken, name='get_auth_token'), 
] 

我试图用这样的邮递员发布:

127.0.0.1:8000/api/login2/ 

但我只能收到此错误

Forbidden (CSRF cookie not set.): /api/login2/ 
[02/Jul/2017 22:49:11] "POST /api/login2/ HTTP/1.1" 403 2891 

我知道有数百个职位这样的,我搜索了很久一个解决方案,但似乎没有任何工作

tryied这样

urlpatterns = patterns('', 
    url('^login2/$', csrf_exempt(ObtainAuthToken)), 
    ... 
) 

from django.utils.decorators import method_decorator 
class LoginView(APIView): 
    @method_decorator(csfr_exempt) 
    def dispatch(self, *args, **kwargs): 
     ... 

,也这

from django.utils.decorators import method_decorator 

@method_decorator(csrf_exempt, name='dispatch') 
class LoginView(APIView): 
     ... 

and this

@method_decorator(csrf_exempt, name='post') 
class ObtainAuthToken(APIView): 
    throttle_classes =() 
    ... 
    @csrf_exempt 
    def post(self, request, *args, **kwargs): 
     serializer = self.serializer_class(data=request.data) 
+0

尝试'@method_decorator(csrf_exempt,name ='post')' - >'@ csrf_exempt' ...看看是否可以解决它? –

+0

你的意思是? @method_decorator(csrf_exempt,名称= '后') 类ObtainAuthToken(APIView): throttle_classes =()... @csrf_exempt 高清张贴(个体经营,要求,* ARGS,** kwargs): 串行= self.serializer_class(data = request.data) ... 仍然没有工作 –

回答

3

您需要使用ObtainAuthToken.as_view()。任何APIView自动使用csrf_exempt()(并且如果您使用的是SessionAuthentication,则显式检查CSRF令牌),但如果您未使用.as_view(),那么这将不起作用。您不必在APIView的作用之上明确使用csrf_exempt

我不确定你为什么不使用第一个网址/login/,但是如果你有这个网址的问题,你会错误地修复它们。

附注:csrf_exempt在功能上设置了一个属性。因此,在post()上使用它是完全没有效果的,因为中间件不会检查post()方法的属性。您需要在dispatch()方法或csrf_exempt(ObtainAuthToken.as_view())上使用它。

+0

这实际上是拯救我的一天! btw即时通讯不使用第一次登录,因为我试图实现一个不同的版本......现在它很好的感谢as_view()!谢谢 –