2013-05-11 8 views
8

Mam następujący kod:CSRF Zwolnione Failure - APIView csrf Django ramy reszta

Problem jest, gdy próbuję uzyskać dostęp do obsługi logowanie/I pojawia się błąd: "CSRF Failed: CSRF ciasteczko nie jest ustawiona."

Co mogę zrobić?

Używam frameworka django.

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 

Odpowiedz

14

Zakładam, że używasz repozytorium django SessionBackend. Ten backend robi implicit CSRF check

Można tego uniknąć przez:

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) 

i ustawić to jako authentication_classes w widoku

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

Faktycznie, lepszy sposób, aby wyłączyć sprawdzanie CSRF wewnątrz SessionAuthentication jest:

from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication 

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

Najprostszy sposób na rozwiązanie tego problemu lem:

Dla że istnieją dwa sposoby uwierzytelniania w DRF see drf auth

BasicAuthentication

SessionAuthentication (domyślnie)

SessionAuthentication ma przymusową kontrolę CSRF, ale BasicAuthentication nie. W ten sposób używam BasicAuthentication w moim widoku zamiast 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({})