Herii
Herii

Reputation: 510

How to use Nuxt $auth inside an axios plugin (How to add Token to all axios requests)

Im looking to use $auth inside my Nuxt project, specially inside an axios plugin.

Here is my code:

plugins/api.js

export default function ({ $axios }, inject) {
  const api = $axios.create({
    headers: {
      common: {
        Accept: 'text/plain, */*',
      },
    },
  })

  // Set baseURL to something different
  api.setBaseURL('http://localhost:4100/')

  // Inject to context as $api
  inject('api', api)
}

Now the problem comes when I try to use $auth from @nuxtjs/auth-next package.

As stated in the docs:

This module globally injects $auth instance, meaning that you can access it anywhere using this.$auth. For plugins, asyncData, fetch, nuxtServerInit and Middleware, you can access it from context.$auth.

I tried the following:

  1. This results in $auth being undefined

    export default function ({ $axios, $auth }, inject) {

  2. This one was near

    export default function ({ $axios, app }, inject) { console.log(app) //This one logs $auth in the object logged console.log(app.$auth) // I don't understand why but this one returns undefined

My main goal here is to make use of this.$auth.strategy.token.get()and pass it (if the token exists of course) to the headers of every request made using this.$api

I have been looking for similar questions and answers but none has helped me to solve this, I could just add the token every time I write this.$api but that would increase the code unnecessarily.

Thanks in advance to all the people for your time and help.

EDIT:

Okay, now I made a test. and the next code is actually logging the $auth object correctly, it seems some time is needed to make it work but now Im afraid that using setTimeout could cause an error because I can't know exactly how much time is needed for $auth to be available.

export default function ({ $axios, app }, inject) {
  setTimeout(() => {
    console.log('After timeout', app.$auth)
  }, 50)

EDIT 2:

So now I have made more tests, and using 0 milliseconds instead of 50 works too, so I will use setTimeout with 0 milliseconds for now, I hope anyone find a better solution or explain why $auth is not available before using setTimeout so I can decide what to do with my code.

EDIT 3:

After trying to wrap all my previous code inside setTimeout I noticed that the code fails, so that isn't a solution.

Upvotes: 6

Views: 5293

Answers (2)

Javaddev
Javaddev

Reputation: 138

Also Nuxt Auth itself has provided a solution for this issue: https://auth.nuxtjs.org/recipes/extend/

Upvotes: 0

Herii
Herii

Reputation: 510

I have found a solution so I will post it so that every person that could have the same problem in the future can solve it.

It turns out that I could easily solve it using interceptors.

export default function ({ $axios, app }, inject) {
  // At this point app.$auth is undefined. (Unless you use setTimeout but that is not a solution)

  //Create axios instance
  const api = $axios.create({
    headers: {
      common: {
        Accept: 'application/json', //accept json
      },
    },
  })
  // Here is the magic, onRequest is an interceptor, so every request made will go trough this, and then we try to access app.$auth inside it, it is defined
  api.onRequest((config) => {
    // Here we check if user is logged in
    if (app.$auth.loggedIn) {
      // If the user is logged in we can now get the token, we get something like `Bearer yourTokenJ9F0JFODJ` but we only need the string without the word **Bearer**, So we split the string using the space as a separator and we access the second position of the array **[1]**

      const token = app.$auth.strategy.token.get().split(' ')[1]
      api.setToken(token, 'Bearer') // Here we specify the token and now it works!!
    }
  })

  // Set baseURL to something different
  api.setBaseURL('http://localhost:4100/')

  // Inject to context as $api
  inject('api', api)
}

Upvotes: 10

Related Questions