0

I am trying to do a simple login page with the Django Rest Framework and I keep getting a csrf token error. To get around this for now, I have appended the @csrf_exempt annotation on my login method which works but is unsecure.

This is my method:

@csrf_exempt
def login(request):
    print(request.COOKIES)
    username = request.POST.get('username')
    password = request.POST.get('password')
    print("username {} password {}".format(username, password))
    user = authenticate(request, username=username, password=password)
    group = None

    if user is not None:
        django_login(request, user)
        request.session.set_expiry(0)
        result = True
        status = 200
    else:
        result = False
        status = 401

    data = {'result': result, 'username': username}

    return HttpResponse(json.dumps(data), content_type="application/json", status=status)

My Rest Framework Settings:

REST_FRAMEWORK = {
    'DATETIME_FORMAT': "%m/%d/%Y %H:%M:%S",
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
     ),
     'DEFAULT_FILTER_BACKENDS': (
         'rest_framework.filters.SearchFilter',
         'django_filters.rest_framework.DjangoFilterBackend',
    ),
    'EXCEPTION_HANDLER':  'common.custom_exception_handler.custom_exception_handler'
 }

Without the csrf_exempt annotation, I get
Forbidden (CSRF token missing or incorrect.): /authentication/login

however, when I print the cookies I actually get a token in my cookie.

{'csrftoken': 'HZc8vPqoad...7eIvTzep', 'sessionid': 'n71c....g5c7'} gets printed when I add the @csrf_exempt annotation back in.

In my angular code, I have also tried to attach the csrf token as a request header with 'X-CSRFToken' but I noticed two things

1) in my request, the X-CSRFToken i obtain from document.cookies is NOT the same as the token above. There are two different CSRF tokens - why?

enter image description here

If you notice, the X-CSRFToken header and the token in the cookie differ. And I receive the same CSRF token missing or incorrect.

2) Even if I remove the use of the JWT Authentication, It has no effect.

I have also tried to use the new XSRF Strategy replacement with the new Cookie strategy in my app.module like this: { provide: XSRFStrategy, useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken') }

But to no avail - I get the same issue described in point (1).

However, when i add the @csrf_exempt annotation back in and check the cookie in the request, The cookie in the image shows up!!

So my main question is: why is the DRF not able to read the token even though the csrf cookie is part of the request?

Karan
  • 1,335
  • 2
  • 14
  • 29
  • CSRF Tokens change on login, it is possible that you added the old csrf token in the header and asked to login, and upon successful login, django sent you the new token in the cookie – rtindru May 30 '18 at 16:23
  • But it never even logged in the first place :/ It throws me the CSRF error upon attempting to log in the first time immediately. However, I feel like that still isn't the issue because when I check the cookie, the csrf token is being sent as a cookie even without me explicitly adding it as a header. – Karan May 30 '18 at 16:49
  • That's how Django CSRF works; here's a quick primer; https://stackoverflow.com/questions/50533524/angular-resetting-csrf-token/50533974#50533974 Read through and we can discuss more – rtindru May 30 '18 at 17:02
  • How are you setting the csrftoken in the header? Where are you getting the value from? – rtindru May 30 '18 at 17:22

0 Answers0