2013-05-11 122 views
8

我有以下代碼:CSRF豁免失敗 - APIView CSRF Django的REST框架

問題是,當我試圖訪問用戶登錄/我得到一個錯誤:「:未設置CSRF餅乾CSRF失敗。」

我該怎麼辦?

我正在使用django rest框架。

urls.py: 

url(r'^user-login/$', 
    csrf_exempt(LoginView.as_view()), 
    name='user-login'), 

views.py: 

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

def post(self, request, format=None): 
    profile = request.POST 

    if ('user_name' not in profile or 'email_address' not in profile or 'oauth_secret' not in profile): 
     return Response(
      {'error': 'No data'}, 
      status=status.HTTP_400_BAD_REQUEST) 

    username = 'l' + profile['user_name'] 
    email_address = profile['email_address'] 
    oauth_secret = profile['oauth_secret'] 
    password = oauth_secret 

回答

14

我假設你使用django rest框架SessionBackend。這個後端做了implicit CSRF check

您可以通過避免這種情況:

from rest_framework.authentication import SessionAuthentication 

class UnsafeSessionAuthentication(SessionAuthentication): 

    def authenticate(self, request): 
     http_request = request._request 
     user = getattr(http_request, 'user', None) 

     if not user or not user.is_active: 
      return None 

     return (user, None) 

並且在視圖

class UnsafeLogin(APIView): 
    permission_classes = (AllowAny,) #maybe not needed in your case 
    authentication_classes = (UnsafeSessionAuthentication,) 

    def post(self, request, *args, **kwargs): 

     username = request.DATA.get("u"); 
     password = request.DATA.get("p"); 

     user = authenticate(username=username, password=password) 
     if user is not None: 
      login(request, user) 

     return redirect("/") 
9

其實它設置爲authentication_classes,更好的方法來禁用內SessionAuthentication CSRF檢查:

from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication 

class SessionAuthentication(OriginalSessionAuthentication): 
    def enforce_csrf(self, request): 
     return 
2

解決此問題的最簡單方法LEM:

對於有在DRF see drf auth

BasicAuthentication

SessionAuthentication(默認)認證兩種方式

SessionAuthentication具有強制CSRF檢查,但BasicAuthentication沒有。 所以我的方式是在我的視圖中使用BasicAuthentication而不是SessionAuthentication。

from rest_framework.authentication import BasicAuthentication 

class UserLogin(generics.CreateAPIView): 
    permission_classes = (permissions.AllowAny,) 
    serializer_class = UserSerializer 
    authentication_classes = (BasicAuthentication,) 

    def post(self, request, *args, **kwargs): 
     return Response({})