Authentication is the process through which a website or app verifies the identity of its users. As the gatekeeper to an app, authentication needs to be secure and reliable. After all, it deals with user information, potentially the most critical data in an app.
Implementing a secure authentication mechanism from scratch could be difficult and can quickly become cumbersome. Where do you save the user data? Should you roll out a database and model the user content type? What about registration, login, and password reset? It doesn't end there. How do you deal with passwords securely?
That's a lot to think about when you just want to dive into the core functionality of the app you're developing. You could build your own authentication mechanism, but do you really need or want to? It may be better to rely on something that's already been built and thoroughly tested.
Strapi, the leading open-source Headless CMS, speeds up the process and gives you the freedom to use your favorite frameworks. Strapi is the leading open-source headless CMS made by developers for deverlopers.. Strapi provides authentication right out of the box; it comes with built-in role-based access control and customizable REST API to perform the main authentication operations.
This is a step-by-step guide on how to implement Strapi-based authentication in a Nuxt.js app. On the frontend, we'll be using Nuxt.js and relying on Nuxt's Auth Module, which is the official zero-boilerplate authentication support for Nuxt.js.
In this article, we'll build two projects:
Here's a preview of what we want to achieve:
To follow this tutorial, make sure you have:
Let's get started!
Begin by creating a Strapi project. Copy and paste the following command line into your terminal to create your first Strapi project.
yarn create strapi-app backend --quickstart
Using the --quickstart
flag at the end of the command to directly create the project in quickstart mode, which uses the default database (SQLite).
Once the installation is complete, your browser automatically opens a new tab.
Complete the form to create your new administrator account.
Now that you've created your Strapi application, you are ready to start a new Nuxt.js project.
In this step, we will use create-nuxt-app to create a new Nuxt project.
Open a terminal or, from Visual Studio Code, open an integrated terminal and use the following command to create a new starter project:
yarn create nuxt-app frontend
After running the command above, you’ll have to answer some questions. Once all questions are answered, it will install all the dependencies.
1 ? Project name: frontend
2 ? Programming language: JavaScript
3 ? Package manager: Yarn
4 ? UI framework: Windi CSS
5 ? Nuxt.js modules: None
6 ? Linting tools: ESLint, Prettier
7 ? Testing framework: None
8 ? Rendering mode: Universal (SSR / SSG)
9 ? Deployment target: Server (Node.js hosting)
10 ? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
11 ? Continuous integration: None
12 ? Version control system: Git
Once the project is created, follow the instructions to install dependencies and start the dev server:
1 cd frontend
2 yarn
3 yarn dev
Now that the dev server is running, open http://localhost:3000/ in your browser.
Good job, you successfully set up both Nuxt and Strapi projects! 🎉
**nuxt auth**
authenticates users using a configurable authentication scheme or by using one of the directly supported providers. It provides an API for triggering authentication and accessing the resulting user information.
Let's install the packages we need. Open a new terminal:
1 # Ctrl + C to close process js
2 cd frontend
yarn add --exact @nuxtjs/auth-next
yarn add @nuxtjs/axios
Then, add the following to the modules
section of nuxt.config.js
:
1 // frontend/nuxt.config.js
2 export default {
3 // Modules: https://go.nuxtjs.dev/config-modules
4 modules: [
5 '@nuxtjs/axios',
6 '@nuxtjs/auth-next'
7 ],
8 }
The auth-module relies on Vuex, a state management pattern + library for Vue.js applications. You can activate the store by creating a new ./store/index.js
file
1 // frontend/store/index.js
2 export const getters = {
3 isAuthenticated(state) {
4 return state.auth.loggedIn
5 },
6 loggedInUser(state) {
7 return state.auth.user
8 },
9 }
You can now start configuring your local scheme.
Schemes define authentication logic, see IANA list of authentication schemes. local
is the default credentials based scheme for flows like JWT (JSON Web Token), which is the authentication process provided by Strapi roles & permissions plugin.
In this guide we will see how to validate a JWT
with Strapi. Let’s map the Strapi authentication endpoints to the local
strategy. Add a new axios
and auth
sections to your nuxt.config.js
:
1 // frontend/nuxt.config.js
2 export default {
3 axios: {
4 baseURL: process.env.STRAPI_URL || 'http://localhost:1337/api'
5 },
6
7 auth: {
8 // Options
9 strategies: {
10 local: {
11 token: {
12 property: 'jwt',
13 },
14 user: {
15 property: false,
16 },
17 endpoints: {
18 login: {
19 url: 'auth/local',
20 method: 'post',
21 },
22 user: {
23 url: 'users/me',
24 method: 'get',
25 },
26 logout: false,
27 },
28 },
29 },
30 }
31 }
Here, you set the base URL that axios will use when making requests. In our case, we are referencing the Strapi API endpoint we set up earlier.
Then, you define the authentication endpoints for the local strategy corresponding to those on your API:
login
: authenticates the user. On successful authentication, the JWT token will be available in the jwt
property of the response object.user
: retrieves the authenticated user's info. If the user is authenticated, the JWT token will be added to the request, allowing Strapi to identify the user.logout
endpoint, since logging out a user is only done locally and doesn't require any request to Strapi's API. The token is simply removed from the local storage when the user logs out.Create a new ./components/Navbar.vue
file, and copy/paste the following code in it:
1 // frontend/components/Navbar.vue
2 <template>
3 <div class="bg-gray-800 py-4 px-4">
4 <NuxtLink class="text-white p-2 hover:bg-gray-700" to="/">Home</NuxtLink>
5 <NuxtLink
6 v-if="!isAuthenticated"
7 class="text-white p-2 hover:bg-gray-700"
8 to="/user/login"
9 >Sign In</NuxtLink
10 >
11 <NuxtLink
12 v-if="!isAuthenticated"
13 class="text-white p-2 hover:bg-gray-700"
14 to="/user/register"
15 >Sign Up</NuxtLink
16 >
17 <NuxtLink
18 v-if="isAuthenticated"
19 class="text-white p-2 hover:bg-gray-700"
20 to="/user/me"
21 >Your profile</NuxtLink
22 >
23 <a
24 v-if="isAuthenticated"
25 class="text-white p-2 hover:bg-gray-700"
26 href="/logout"
27 @click.prevent="userLogout"
28 >Logout</a
29 >
30 </div>
31 </template>
1 <script>
2 import { mapGetters } from 'vuex'
3 export default {
4 computed: {
5 ...mapGetters(['isAuthenticated']),
6 },
7 methods: {
8 async userLogout() {
9 await this.$auth.logout()
10 },
11 },
12 }
13 </script>
In the code above, we have created a navbar component using Tailwind CSS. Apart from that, we've defined the computed property isAuthenticated
and userLogout
method used in the component's template.
Add your navbar component to all your pages by extending the main layout. Add a new layouts/default.vue
file, and copy/paste the following code in it:
1 // frontend/layouts/default.vue
2 <template>
3 <div>
4 <Navbar />
5 <nuxt />
6 </div>
7 </template>
Great! After completing the navbar:
yarn dev
to start the development server.http://localhost:3000
to view your application.Create a new ./pages/user/Login.vue
file, and copy/paste the following code in it:
1 // frontend/pages/user/Login.vue
2 <template>
3 <div class="max-w-md w-full mx-auto mt-8">
4 <h1 class="text-3xl font-extrabold mb-4">Sign in</h1>
5 <form @submit.prevent="userLogin">
6 <div
7 v-if="err"
8 class="
9 p-4
10 mb-4
11 text-sm text-red-700
12 bg-red-100
13 rounded-lg
14 dark:bg-red-200 dark:text-red-800
15 "
16 role="alert"
17 >
18 {{ err }}
19 </div>
20 <div class="mb-6">
21 <label
22 for="email"
23 class="
24 block
25 mb-2
26 text-sm
27 font-medium
28 text-gray-900
29 dark:text-gray-300
30 "
31 >Your email</label
32 >
33 <input
34 v-model="email"
35 type="email"
36 class="
37 shadow-sm
38 bg-gray-50
39 border border-gray-300
40 text-gray-900 text-sm
41 rounded-lg
42 focus:ring-blue-500 focus:border-blue-500
43 block
44 w-full
45 p-2.5
46 dark:bg-gray-700
47 dark:border-gray-600
48 dark:placeholder-gray-400
49 dark:text-white
50 dark:focus:ring-blue-500
51 dark:focus:border-blue-500
52 dark:shadow-sm-light
53 "
54 placeholder="name@strapi.io"
55 required
56 />
57 </div>
58 <div class="mb-6">
59 <label
60 for="password"
61 class="
62 block
63 mb-2
64 text-sm
65 font-medium
66 text-gray-900
67 dark:text-gray-300
68 "
69 >Your password</label
70 >
71 <input
72 v-model="password"
73 type="password"
74 class="
75 shadow-sm
76 bg-gray-50
77 border border-gray-300
78 text-gray-900 text-sm
79 rounded-lg
80 focus:ring-blue-500 focus:border-blue-500
81 block
82 w-full
83 p-2.5
84 dark:bg-gray-700
85 dark:border-gray-600
86 dark:placeholder-gray-400
87 dark:text-white
88 dark:focus:ring-blue-500
89 dark:focus:border-blue-500
90 dark:shadow-sm-light
91 "
92 required
93 />
94 <p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
95 <NuxtLink
96 class="font-medium text-blue-600 hover:underline dark:text-blue-500"
97 to="/user/forgot"
98 >Reset password</NuxtLink
99 >?
100 </p>
101 </div>
102 <button
103 type="submit"
104 class="
105 text-white
106 bg-blue-700
107 hover:bg-blue-800
108 focus:ring-4 focus:outline-none focus:ring-blue-300
109 font-medium
110 rounded-lg
111 text-sm
112 px-5
113 py-2.5
114 text-center
115 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
116 "
117 >
118 Sign in
119 </button>
120 </form>
121 </div>
122 </template>
1 <script>
2 export default {
3 auth: 'guest',
4 data() {
5 return {
6 err: null,
7 email: '',
8 password: '',
9 }
10 },
11 methods: {
12 async userLogin() {
13 try {
14 await this.$auth.loginWith('local', {
15 data: { identifier: this.email, password: this.password },
16 })
17 } catch (e) {
18 if (e.response) this.err = e.response.data.error.message
19 }
20 },
21 },
22 }
23 </script>
In the code above, we've defined three properties err
, email
and password
used in the component's template and userLogin
method which log in the user after sending the data to the Strapi application. An error notification will be displayed if login attempt is not successful, If not the user will be redirected to the homepage.
The auth: 'guest``'
middleware help redirected the user to the homepage, if already logged in.
Create a new ./pages/user/Register.vue
file, and copy/paste the following code in it:
1 // frontend/pages/user/Register.vue
2 <template>
3 <div class="max-w-md w-full mx-auto mt-8">
4 <h1 class="text-3xl font-extrabold mb-4">Sign up</h1>
5 <form @submit.prevent="userRegister">
6 <div
7 v-if="err"
8 class="
9 p-4
10 mb-4
11 text-sm text-red-700
12 bg-red-100
13 rounded-lg
14 dark:bg-red-200 dark:text-red-800
15 "
16 role="alert"
17 >
18 {{ err }}
19 </div>
20 <div
21 v-if="success"
22 class="
23 p-4
24 mb-4
25 text-sm text-green-700
26 bg-green-100
27 rounded-lg
28 dark:bg-green-200 dark:text-green-800
29 "
30 role="alert"
31 >
32 Your account has been created successfully you can now
33 <NuxtLink class="font-medium" to="/user/login">Login</NuxtLink>
34 </div>
35 <div class="mb-6">
36 <label
37 for="username"
38 class="
39 block
40 mb-2
41 text-sm
42 font-medium
43 text-gray-900
44 dark:text-gray-300
45 "
46 >Your username</label
47 >
48 <input
49 v-model="username"
50 type="text"
51 class="
52 shadow-sm
53 bg-gray-50
54 border border-gray-300
55 text-gray-900 text-sm
56 rounded-lg
57 focus:ring-blue-500 focus:border-blue-500
58 block
59 w-full
60 p-2.5
61 dark:bg-gray-700
62 dark:border-gray-600
63 dark:placeholder-gray-400
64 dark:text-white
65 dark:focus:ring-blue-500
66 dark:focus:border-blue-500
67 dark:shadow-sm-light
68 "
69 placeholder="name"
70 required
71 />
72 </div>
73 <div class="mb-6">
74 <label
75 for="email"
76 class="
77 block
78 mb-2
79 text-sm
80 font-medium
81 text-gray-900
82 dark:text-gray-300
83 "
84 >Your email</label
85 >
86 <input
87 v-model="email"
88 type="email"
89 class="
90 shadow-sm
91 bg-gray-50
92 border border-gray-300
93 text-gray-900 text-sm
94 rounded-lg
95 focus:ring-blue-500 focus:border-blue-500
96 block
97 w-full
98 p-2.5
99 dark:bg-gray-700
100 dark:border-gray-600
101 dark:placeholder-gray-400
102 dark:text-white
103 dark:focus:ring-blue-500
104 dark:focus:border-blue-500
105 dark:shadow-sm-light
106 "
107 placeholder="name@strapi.io"
108 required
109 />
110 </div>
111 <div class="mb-6">
112 <label
113 for="password"
114 class="
115 block
116 mb-2
117 text-sm
118 font-medium
119 text-gray-900
120 dark:text-gray-300
121 "
122 >Your password</label
123 >
124 <input
125 v-model="password"
126 type="password"
127 class="
128 shadow-sm
129 bg-gray-50
130 border border-gray-300
131 text-gray-900 text-sm
132 rounded-lg
133 focus:ring-blue-500 focus:border-blue-500
134 block
135 w-full
136 p-2.5
137 dark:bg-gray-700
138 dark:border-gray-600
139 dark:placeholder-gray-400
140 dark:text-white
141 dark:focus:ring-blue-500
142 dark:focus:border-blue-500
143 dark:shadow-sm-light
144 "
145 required
146 />
147 </div>
148 <button
149 type="submit"
150 class="
151 text-white
152 bg-blue-700
153 hover:bg-blue-800
154 focus:ring-4 focus:outline-none focus:ring-blue-300
155 font-medium
156 rounded-lg
157 text-sm
158 px-5
159 py-2.5
160 text-center
161 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
162 "
163 >
164 Sign up
165 </button>
166 </form>
167 </div>
168 </template>
1 <script>
2 export default {
3 auth: 'guest',
4 data() {
5 return {
6 success: false,
7 err: null,
8 username: '',
9 email: '',
10 password: '',
11 }
12 },
13 methods: {
14 async userRegister() {
15 try {
16 this.$axios.setToken(false)
17 await this.$axios.post('auth/local/register', {
18 username: this.username,
19 email: this.email,
20 password: this.password,
21 })
22 this.success = true
23 } catch (e) {
24 if (e.response) this.err = e.response.data.error.message
25 }
26 },
27 },
28 }
29 </script>
In the code above, we've defined two more properties success
and username
used to display a success message after a successful registration.
Time for the user profile page.
Create a new ./pages/user/Me.vue
file, and copy/paste the following code in it:
1 // frontend/pages/user/Me.vue
2 <template>
3 <div class="max-w-md w-full mx-auto mt-8">
4 <h1 class="text-3xl font-extrabold mb-4">Your profile</h1>
5 <form @submit.prevent="userLogin">
6 <div class="mb-6">
7 <label
8 for="email"
9 class="
10 block
11 mb-2
12 text-sm
13 font-medium
14 text-gray-900
15 dark:text-gray-300
16 "
17 >Your email</label
18 >
19 <input
20 type="email"
21 class="
22 mb-6
23 bg-gray-100
24 border border-gray-300
25 text-gray-900 text-sm
26 rounded-lg
27 focus:ring-blue-500 focus:border-blue-500
28 block
29 w-full
30 p-2.5
31 cursor-not-allowed
32 dark:bg-gray-700
33 dark:border-gray-600
34 dark:placeholder-gray-500
35 dark:text-gray-500
36 dark:focus:ring-blue-500
37 dark:focus:border-blue-500
38 "
39 :value="loggedInUser.email"
40 disabled
41 />
42 </div>
43 <div class="mb-6">
44 <label
45 for="username"
46 class="
47 block
48 mb-2
49 text-sm
50 font-medium
51 text-gray-900
52 dark:text-gray-300
53 "
54 >Your username</label
55 >
56 <input
57 type="text"
58 class="
59 mb-6
60 bg-gray-100
61 border border-gray-300
62 text-gray-900 text-sm
63 rounded-lg
64 focus:ring-blue-500 focus:border-blue-500
65 block
66 w-full
67 p-2.5
68 cursor-not-allowed
69 dark:bg-gray-700
70 dark:border-gray-600
71 dark:placeholder-gray-500
72 dark:text-gray-500
73 dark:focus:ring-blue-500
74 dark:focus:border-blue-500
75 "
76 :value="loggedInUser.username"
77 disabled
78 />
79 </div>
80 </form>
81 </div>
82 </template>
1 <script>
2 import { mapGetters } from 'vuex'
3 export default {
4 middleware: 'auth',
5 computed: {
6 ...mapGetters(['loggedInUser']),
7 },
8 }
9 </script>
The auth
middleware guarantees that only logged in users can access this page.
Let's now implement a password reset mechanism.
This will be achieved with the following workflow:
Before implementing the password reset feature. We need to enable the Public Role permissions for the auth/reset-password
and auth/forgot-password
endpoints.
To do so, open your Strapi application at http://localhost:1337/admin, from the left sidebar of the admin dashboard, click Settings, Roles, Edit Public, open Users-permissions, check both forgotPassword and resetPassword, then click Save.
Create a new ./pages/user/Forgot.vue
file, and copy/paste the following code in it:
1 // frontend/pages/user/Forgot.vue
2 <template>
3 <div class="max-w-md w-full mx-auto mt-8">
4 <h1 class="text-3xl font-extrabold mb-4">New password</h1>
5 <form @submit.prevent="userPassword">
6 <div
7 v-if="err"
8 class="
9 p-4
10 mb-4
11 text-sm text-red-700
12 bg-red-100
13 rounded-lg
14 dark:bg-red-200 dark:text-red-800
15 "
16 role="alert"
17 >
18 {{ err }}
19 </div>
20 <div class="mb-6">
21 <label
22 for="email"
23 class="
24 block
25 mb-2
26 text-sm
27 font-medium
28 text-gray-900
29 dark:text-gray-300
30 "
31 >Your email</label
32 >
33 <input
34 v-model="email"
35 type="email"
36 class="
37 shadow-sm
38 bg-gray-50
39 border border-gray-300
40 text-gray-900 text-sm
41 rounded-lg
42 focus:ring-blue-500 focus:border-blue-500
43 block
44 w-full
45 p-2.5
46 dark:bg-gray-700
47 dark:border-gray-600
48 dark:placeholder-gray-400
49 dark:text-white
50 dark:focus:ring-blue-500
51 dark:focus:border-blue-500
52 dark:shadow-sm-light
53 "
54 placeholder="name@strapi.io"
55 required
56 />
57 </div>
58 <button
59 type="submit"
60 class="
61 text-white
62 bg-blue-700
63 hover:bg-blue-800
64 focus:ring-4 focus:outline-none focus:ring-blue-300
65 font-medium
66 rounded-lg
67 text-sm
68 px-5
69 py-2.5
70 text-center
71 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
72 "
73 >
74 New password
75 </button>
76 </form>
77 </div>
78 </template>
1 <script>
2 export default {
3 auth: 'guest',
4 data() {
5 return {
6 err: null,
7 email: '',
8 }
9 },
10 methods: {
11 async userPassword() {
12 try {
13 await this.$axios.post('auth/forgot-password', {
14 email: this.email,
15 })
16 } catch (e) {
17 if (e.response) this.err = e.response.data.error.message
18 }
19 },
20 },
21 }
22 </script>
In the code above, we've defined a new userPassword
method that sends a request to Strapi's auth/forgot-password
endpoint. If the email address exists in Strapi's user database, an email is sent with a link to a reset password page in the frontend app.
This link contains an empty URL with code
param which is required to reset user password. To specify a URL, there’s some simple configuration you need to do inside the admin panel.
From the left sidebar of the admin dashboard, click Settings, Advanced settings, paste http://localhost:3000/user/reset
in the “Reset password page" field, then click Save.
Let's now create the reset page that will allow the user to define a new password.
Create a new file ./pages/user/Reset.vue
and paste the following code into it:
1 // frontend/pages/user/Rest.vue
2 <template>
3 <div class="max-w-md w-full mx-auto mt-8">
4 <h1 class="text-3xl font-extrabold mb-4">New password</h1>
5 <form @submit.prevent="userPassword">
6 <div
7 v-if="err"
8 class="
9 p-4
10 mb-4
11 text-sm text-red-700
12 bg-red-100
13 rounded-lg
14 dark:bg-red-200 dark:text-red-800
15 "
16 role="alert"
17 >
18 {{ err }}
19 </div>
20 <div
21 v-if="success"
22 class="
23 p-4
24 mb-4
25 text-sm text-green-700
26 bg-green-100
27 rounded-lg
28 dark:bg-green-200 dark:text-green-800
29 "
30 role="alert"
31 >
32 Your password has been updated successfully you can now
33 <NuxtLink class="font-medium" to="/user/login">Login</NuxtLink>
34 </div>
35 <div class="mb-6">
36 <label
37 for="password"
38 class="
39 block
40 mb-2
41 text-sm
42 font-medium
43 text-gray-900
44 dark:text-gray-300
45 "
46 >New password</label
47 >
48 <input
49 v-model="password"
50 type="password"
51 class="
52 shadow-sm
53 bg-gray-50
54 border border-gray-300
55 text-gray-900 text-sm
56 rounded-lg
57 focus:ring-blue-500 focus:border-blue-500
58 block
59 w-full
60 p-2.5
61 dark:bg-gray-700
62 dark:border-gray-600
63 dark:placeholder-gray-400
64 dark:text-white
65 dark:focus:ring-blue-500
66 dark:focus:border-blue-500
67 dark:shadow-sm-light
68 "
69 required
70 />
71 </div>
72 <div class="mb-6">
73 <label
74 for="password-confirmation"
75 class="
76 block
77 mb-2
78 text-sm
79 font-medium
80 text-gray-900
81 dark:text-gray-300
82 "
83 >Confirm new password</label
84 >
85 <input
86 v-model="passwordConfirmation"
87 type="password"
88 class="
89 shadow-sm
90 bg-gray-50
91 border border-gray-300
92 text-gray-900 text-sm
93 rounded-lg
94 focus:ring-blue-500 focus:border-blue-500
95 block
96 w-full
97 p-2.5
98 dark:bg-gray-700
99 dark:border-gray-600
100 dark:placeholder-gray-400
101 dark:text-white
102 dark:focus:ring-blue-500
103 dark:focus:border-blue-500
104 dark:shadow-sm-light
105 "
106 required
107 />
108 </div>
109 <button
110 type="submit"
111 class="
112 text-white
113 bg-blue-700
114 hover:bg-blue-800
115 focus:ring-4 focus:outline-none focus:ring-blue-300
116 font-medium
117 rounded-lg
118 text-sm
119 px-5
120 py-2.5
121 text-center
122 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
123 "
124 >
125 New password
126 </button>
127 </form>
128 </div>
129 </template>
1 <script>
2 export default {
3 auth: 'guest',
4 data() {
5 return {
6 success: false,
7 err: null,
8 password: '',
9 passwordConfirmation: '',
10 }
11 },
12 methods: {
13 async userPassword() {
14 try {
15 await this.$axios.post('auth/reset-password', {
16 code: this.$route.query.code,
17 password: this.password,
18 passwordConfirmation: this.passwordConfirmation,
19 })
20 this.success = true
21 } catch (e) {
22 if (e.response) this.err = e.response.data.error.message
23 }
24 },
25 },
26 }
27 </script>
In the code above, we've defined three propreties.
password
, which will be our new passwordpasswordConfirmation
, to make sure that the user didn’t make any mistakecode
, the code contained in the reset link sent to the user via emailTo test the new functionality, run npm run dev
to start the development server.
Then, visit http://localhost:3000/forgot in your browser, go through the forgot password process and then try the reset, starting with the reset link sent to your email address.
Awesome! We've done a lot, but there's still something missing before we wrap up.
If the JWT token expires, subsequent requests to Strapi will return a 401 Unauthorized error.
To deal with this, we'll intercept error responses in axios
and check if the status code is 401
. If it is, we redirect the user to the login page.
Create a new ./plugins/axios.js
file, and paste the following:
1 export default function ({ $axios, redirect }) {
2 $axios.onError((error) => {
3 const code = parseInt(error.response && error.response.status)
4 if (code === 401) redirect('/user/login')
5 })
6 }
Now, let’s import the new plugin in nuxt.config.js
, add the following to your plugins section:
1 plugins: ['~plugins/axios'],
Now, when the JWT expires the user will be gracefully redirected to the login page.
Hopefully, you've found this tutorial helpful for implementing Strapi authentication in your Nuxt app! You should now have a fully-built, ready to be deployed in production authentication flow, through which users can register, login, and reset their password.
A Front-end developer, Acquia Certified and React.js expert.