0
votes

I'm trying to implement authentication on my frontend (which is written in NuxtJS) using cookies as opposed to local storage.

I'm using the nuxt-auth package, with the following configuration:-

auth: {
  strategies: {
    cookie: {
      token: {
        required: false,
        type: false,
      },
      user: {
        property: false,
      },
      endpoints: {
        login: {
          url: '/auth/token/login/',
        },
        user: {
          url: '/auth/users/me/',
          method: 'get',
        },
        logout: {
          url: '/auth/token/logout',
        },
      },
    },
    local: false,
  },
}

My backend is django with rest framework and djoser with the following config:-

DJOSER = {
    'CREATE_SESSION_ON_LOGIN': True
}

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication'
    ),
}

When I call the auth login method in my frontend, like this:-

this.$auth.loginWith('cookie', {
  data: this.login,
})

it all works as expected.

  1. The frontend calls /auth/token/login.
  2. The backend authenticates the user and sets the cookie in the browser.
  3. The frontend calls /auth/users/me which returns the user data and the frontend sets loggedIn to true.

But when the user tries to logout in the frontend, the POST request fails because the CSRF token is not set.

HTTP 403: CSRF Failed: CSRF token missing or incorrect.

I've tried all sorts of other ways to set this stuff up and none of them seem to work any better:-

  1. Use localstorage.

    • this is not very secure and should not be used
  2. Use TokenAuthentication instead of SessionAuthentication

    • nuxt.config.js looks like this:-

    auth: { strategies: { cookie: { token: { property: 'auth_token', type: 'Token', }, user: { property: false, }, endpoints: { login: { url: '/auth/token/login/', }, user: { url: '/auth/users/me/', method: 'get', }, logout: { url: '/auth/token/logout', }, }, }, local: false, }, }

    but the backend is looking for a header value for Authorization with the auth_token and this is not sent in the request.

Am I approaching this the right way or is there something else I need to do? I'm fairly new to the frontend stuff here so it's driving me mad not being able to get it to work and I'd really appreciate some help.

1

1 Answers

1
votes

For anyone that is struggling with the same issue, I have found the solution.

The problem was that the default for xsrfHeaderName in axios does not match the value that the django backend is looking for. So the csrftoken from the cookie is not sent in the HTTP headers.

To fix it, you need to create a plugin that looks like this:-

export default function ({ $axios }) {
  $axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'
  $axios.defaults.xsrfCookieName = 'csrftoken'
}

and add it in to the plugins section of the nuxt.config.js:-

'~/plugins/axios',