Igal
Igal

Reputation: 6103

How to set $axios token with Nuxt auth module?

Untill recently I used my own register/login implementation in my Nuxt project, where after successful register/login I was able to do this.$axios.setToken(token, 'Bearer') and it would set the authorization header globally on axios reguests. Now I had to refactor the app and use Nuxt auth module. But now it seems I can't set this header.

This is my auth configuration:

auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: '/auth/local', method: 'post', propertyName: 'jwt' },
          logout: false,
          user: { url: '/users/me', method: 'get', propertyName: false }
        },
      }
    },
    redirect: {
      login: '/login',
      home: '/home',
      user: '/users/me'
    },
}

I thought auth was supposed to add this authorization automatically, since it has globalToken set to true by default, but it didn't have it. So I tried to specify it explicitly:

tokenRequired: true,
tokenType: 'bearer',
globalToken: true,
autoFetchUser: true

It didn't help. So in the register/login methods I tried to set the token myself, both on axios and $auth modules:

await this.$auth.loginWith('local', {
    data
  }).then(({data}) => {
    this.$apolloHelpers.onLogin(data.jwt)
    this.$axios.setToken(data.jwt, 'Bearer')
    this.$auth.setToken('local', `Bearer ${data.jwt}`)
    ...

Also no effect. Though at some point it seems I was able to send only one request successfully, and I saw it did have the Authorization header on the request, but when I switched page and tried to send another request - again it didn't have the header and the request failed with error 403.

So I tried one more thing - in my default layout, in beforeMount() hook, I tried to check if the user is logged in and if he is - set the header:

if (this.$auth.loggedIn) {
  this.$axios.setToken(this.$auth.getToken('local'))
}

Again one request was sent successfully, but when switched to another page and tried to send another request - 403.

Instead of $axios.setToken() I tried to set Authorization header:

this.$axios.defaults.headers.common.Authorization = `${this.$auth.getToken('local')}`

And again - one request successful, the other - 403

Why is is happening? How can I set that Authorization header to be present on all requests after register/login or if the user refreshes the page and he is already logged in?

Upvotes: 3

Views: 10290

Answers (2)

AFX
AFX

Reputation: 366

Here is a solution:

  1. Create a new plugin like /plugins/axios.js

  2. Register this plugin in nuxt config:

    plugins: [
            '~/plugins/axios.js'
    ]
    
  3. Write your token check and update method

I assume that the token refresh is an async method that resides in your store.

    export default function ({ $axios, store}) {
        $axios.onRequest(async (config) => {
            try {
                /// Store action to get or retrieve a token if it has expired
                const token = await store.dispatch('auth/getIdToken')
                 this.$axios.setToken(token, 'Bearer')
            } catch (error) {
                console.log("Could not update token:", error)
            }
            return config
        })
    
    }

The crucial part is to return config so that Axios can continue with the request.

Credits go to jonasjancarik: https://github.com/nuxt-community/axios-module/issues/482

Upvotes: 1

power-cut
power-cut

Reputation: 1498

Well, one way can be using nuxtServerInit

Once you have fetched the jwt token and saved to either cookies/localstorage, subsequently you can use $axios.setToken.for global access. Below is the sample code to give you an idea.

actions: {
      nuxtServerInit({ dispatch, commit, app }, context) {
        const cookies = cparse.parse(context.req.headers.cookie || '')
        if (cookies.hasOwnProperty('x-access-token')) {
          app.$axios.setToken(cookies['x-access-token'], 'Bearer')
        }
      },
    }

Upvotes: 1

Related Questions