ajaxdjangocsrfcsrf-protectiondjango-csrf

Django - Login - Forbidden (CSRF token missing or incorrect.):


I am getting the Forbidden (CSRF token missing or incorrect.) error when I try to use login page.

The scenario is as follows:

  1. An user has two tabs open.
  2. Both tabs are login pages.
  3. In tab 1, user successfully logged in, and was redirected to a new page where login is required.
  4. In tab 2, user hasn't refreshed the page, and is still in the login page. In the Django backend, user is already authenticated, but the front-end template hasn't noticed it yet.
  5. In tab 2, when I click on login button, I get Forbidden (CSRF token missing or incorrect.) error.
  6. I made sure that csrf_token is in the form.
  7. This error occurs only when I'm using two tabs.
  8. I'm using AJAX

Why is this happening? How can I fix it?

I don't know this would help, but here is my views.py for login

class Login_View(LoginView):

    template_name = 'login.html'

    def post(self, request, *args, **kwargs):
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)

        response_data = {}
        if user is not None:
            if user.is_active:
                login(request, user)
                response_data['result'] = 'success'
            else:
                return HttpResponse("Inactive user.")
        else:
            response_data['result'] = 'fail'

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

Solution

  • The reason is addressed in the documentation here:

    For security reasons, CSRF tokens are rotated each time a user logs in. Any page with a form generated before a login will have an old, invalid CSRF token and need to be reloaded. This might happen if a user uses the back button after a login or if they log in a different browser tab.

    As for fixing it, there's neither a straightforward way nor a great reason to do so. If the user encounters an error in this unlikely scenario all they have to do is reload the page. So I wouldn't bother if I were you.