User authentication is something we need to handle on 99% of our Nuxt projects. This feature is widely used, especially when talking about Javascript, which is very divided in implementation approaches. Fortunately, Nuxt not only added a module specifically made for standardizing this, but it completed it with great documentation!
Nuxt-auth is the module I am talking about and offers the possibility to configure a flow that perfectly fits your needs. You can either use some of the directly supported providers or strategies or create a custom schema of your own.
This article will cover a complete setup for a Nuxt app that should handle a token refresh scheme.
Right now, the auth module has two major versions we can choose from. Their statuses can be checked here. The v5 option does come with more documentation, features, and fixes, but unfortunately, the API can still undergo some changes. After using it for some time, I can confirm that no breaking changes were added, but you should be mindful of this when choosing your approach. On the other hand, the v4 option does not include support for the refresh strategy, which was confirmed by the Nuxt contributors here.
So, let’s get started!
First of all, we need to add auth-next
& axios
as dependencies:
Then, we need to add them to the modules in nuxt.config.js
:
Ensure you are using auth-next v5
, as it has more features, including the refresh token strategy. Also, make sure the Vuex store is active.
The auth
middleware can be enabled either per route or globally. This is the default middleware, but you can also create custom ones.
Setting per route:
Setting globally:
Removing middleware for specific components after globally set:
Custom middlewares can be set. For example, if we have multiple user types, we would add an option for the middleware to have:
There are a lot of tricks that we can do. For example, we can set the default redirects for our auth middleware:
First of all, let’s start with our Axios settings:
Then, we can handle the login inside our component. For this example, we’ll use a regular email & password login, but it can be customized:
You can see that we used login with local
Inside our component. This is also set up in our nuxt.config.js
file:
Now, when hitting the button that calls handleLogin
from the component, we will see the response from the login method from our API (in my case, localhost:3000/api/v1/login
).
The case that I considered returns a JSON like this:
That is why the user endpoint has false
as a value. If we needed to do another call to fetch the user after the login was done, we would need to set that up and play with the autoFetch
option.
We only have the successful API call for now, but going to any component that uses middleware: ['auth']
will redirect us back to login. For this, we will need to set the token and the user inside the store so that the $auth
will consider our user logged in.
Let’s say that after the login, we want to redirect to the user’s profile page. Retrieving the user right after the login is a good idea, as it will be put in store, and we can retrieve it from there. So, right after login, our page will handle two things: refreshing the user data and logging out.
Inside our nuxt.config.js
, we already set the inside of the endpoints object that logout: false
. Here, we would need to add the URL if the backend also handles the logout, but that is not required in our case.
After that, we can already use the logout. Inside our component, our button action would be @click="handleLogout"
with the logic being:
This will automatically remove the logged-in details from the store. After this action, the middleware will automatically redirect the user to the selected route when the state is not logged in.
By default, the nuxt-auth has a user
option, where it stores the user details right after login. It can either fetch them right after a successful login or, in our case, get them from the login API response.
The way we configured this, our user will be taken from: user: { url: '/api/v1/profile', method: 'get' }
. The property
value is false
because, for that call, the details will be in the root of the object.
On the profile page, we can just have the user input like this:
This way, even when refreshing the page, the user will still be stored, and we will not be logged out.
Nuxt-auth v5 added the refresh token strategy. It has a default refresh scheme
. It will require us to add these to our nuxt.config.js
:
This implementation has the default logic setup: when using this.$auth.refreshTokens()
, it will use the data in the $auth.refreshToken.get()
and send it to the defined endpoint. Without having the scheme refresh and the refreshToken
option in the strategy, we would not be able to set these up. Also, having these two will make the next line have a lot more sense, as the first parameter is the access token, and the second one is the refresh token, which we can only use now:
But in our case, the refresh token API call needs a little more. Using the example above, the API call will be: POST /api/v1/token with { refresh_token: ‘refresh_token_from_$auth' }
. Our API needs parameters like: { grant_type: 'refresh_token', refresh_token: 'refresh_token' }
. To fix this, we can use url: '/api/v1/token?grant_type=refresh_token'
as the refresh endpoint URL.
If a more complex refresh token logic needs to be handled, we can also create a custom scheme and refresh controller. It will look something like this:
This way, anytime the refreshTokens
method is called, the custom refresh logic will be triggered.
The logic to intercept all 401 requests can be done in the plugins/axios.js
file, with something like:
The benefit of using something like this is that it makes your code look a lot cleaner and have all the auth methods in the same place. You can retrieve the token, the user, or the state just by using $auth
, and you don’t need to implement the auth methods using $axios
, which makes it easier to separate and handle individually.
I hope this guide helped you learn more about Nuxt-auth and how you can use it yourself. If you’ve enjoyed this article, you should definitely check out the other web development topics we have on our blog!
Stay up to date with the tech solutions we build for startups, scale-ups and companies around the world. Read tech trends and news about what we do besides building apps.