Question: Django session causes angular with JWT "token missing or incorrect" error

Question

Django session causes angular with JWT "token missing or incorrect" error

Answers 1
Added at 2017-01-05 22:01
Tags
Question

Setup

An angular application (~1.5) and django with django (1.9.9) rest framework (3.5.3) running on a server with nginx serving the client directly as static files from / and the api through uwsgi from /api

djangorestframework-jwt is in use to provide and validate the JWT tokens for the client.

Reproducing the error:

  1. User logs into the client front end (angular app) successfully.

  2. User clicks a link and GETs some data from the api.

  3. User clicks to edit the data and changes form data and PUTs it to the api

  4. All is well

  5. User gots to /api and logs in via the DRF browsable API with same username and password

  6. Goes back to / and tries to submit a form with PUT again.

  7. Angular forwards the following error from the django server.

{"data":{"detail":"CSRF Failed: CSRF token missing or incorrect."},"status":403, JWT..., "statusText":"Forbidden"}

Finding the cause

Trying to narrow down the issue, I find that there is no csrf cookie nor session cookie found after logging in with the client app. I'm using JWT for authentication, so it shouldn't need any session.

The JWT token is being saved to local storage, not cookies.

After logging into the /api or /administration applications which are handled by django without angular at all, a csrftoken cookie and session cookie are set for that domain.

If I delete the csrf cookie, the angular app still can't PUT or POST. But if I delete the session cookie, it starts to work properly again.

Question

How should I be setting up the Django and/or Angular apps so that the user can login to either one without causing conflict?

Things I've considered

  1. If users don't login to the backend app at all, there is no problem for them. But some will need to occasionally.

  2. If I cause the session cookie to be deleted by Angular, the user will be logged out of the Django app, causing frustration if they need to have both open.

Solution

In working on clarifying this well enough to write a SO post, I've found a solution. Essentially, change Django settings to authenticate against the JWT first, so it never tries to check the session.

See below for more detail.

Answers to

Django session causes angular with JWT "token missing or incorrect" error

nr: #1 dodano: 2017-01-05 22:01

Since Django tends to process settings in the order they are listed, I tried moving the JSONWebTokenAuthentication line to the top of the list instead of the bottom as it would normally be when following the example on the REST framework JWT Auth docs page.

This worked out. So instead of throwing away the question I was almost done with, I've posted it here for your reading enjoyment.

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

A misleading feature of this error is that the csrf token didn't seem to be the actual problem. It was the session token that angular was passing back because angular was being served from the same host as the API.

Source Show
◀ Wstecz