Simply copy and paste the following command line in your terminal to create your first Strapi project.
npx create-strapi-app
my-project
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
2
3
4
5
6
7
8
9
10
11
12
? Project name: frontend
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: Windi CSS
? Nuxt.js modules: None
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git
Once the project is created, follow the instructions to install dependencies and start the dev server:
1
2
3
cd frontend
yarn
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
2
# Ctrl + C to close process js
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
2
3
4
5
6
7
8
// frontend/nuxt.config.js
export default {
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
'@nuxtjs/axios',
'@nuxtjs/auth-next'
],
}
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
2
3
4
5
6
7
8
9
// frontend/store/index.js
export const getters = {
isAuthenticated(state) {
return state.auth.loggedIn
},
loggedInUser(state) {
return state.auth.user
},
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// frontend/nuxt.config.js
export default {
axios: {
baseURL: process.env.STRAPI_URL || 'http://localhost:1337/api'
},
auth: {
// Options
strategies: {
local: {
token: {
property: 'jwt',
},
user: {
property: false,
},
endpoints: {
login: {
url: 'auth/local',
method: 'post',
},
user: {
url: 'users/me',
method: 'get',
},
logout: false,
},
},
},
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// frontend/components/Navbar.vue
<template>
<div class="bg-gray-800 py-4 px-4">
<NuxtLink class="text-white p-2 hover:bg-gray-700" to="/">Home</NuxtLink>
<NuxtLink
v-if="!isAuthenticated"
class="text-white p-2 hover:bg-gray-700"
to="/user/login"
>Sign In</NuxtLink
>
<NuxtLink
v-if="!isAuthenticated"
class="text-white p-2 hover:bg-gray-700"
to="/user/register"
>Sign Up</NuxtLink
>
<NuxtLink
v-if="isAuthenticated"
class="text-white p-2 hover:bg-gray-700"
to="/user/me"
>Your profile</NuxtLink
>
<a
v-if="isAuthenticated"
class="text-white p-2 hover:bg-gray-700"
href="/logout"
@click.prevent="userLogout"
>Logout</a
>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['isAuthenticated']),
},
methods: {
async userLogout() {
await this.$auth.logout()
},
},
}
</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
2
3
4
5
6
7
// frontend/layouts/default.vue
<template>
<div>
<Navbar />
<nuxt />
</div>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// frontend/pages/user/Login.vue
<template>
<div class="max-w-md w-full mx-auto mt-8">
<h1 class="text-3xl font-extrabold mb-4">Sign in</h1>
<form @submit.prevent="userLogin">
<div
v-if="err"
class="
p-4
mb-4
text-sm text-red-700
bg-red-100
rounded-lg
dark:bg-red-200 dark:text-red-800
"
role="alert"
>
{{ err }}
</div>
<div class="mb-6">
<label
for="email"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your email</label
>
<input
v-model="email"
type="email"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
placeholder="name@strapi.io"
required
/>
</div>
<div class="mb-6">
<label
for="password"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your password</label
>
<input
v-model="password"
type="password"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
required
/>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
<NuxtLink
class="font-medium text-blue-600 hover:underline dark:text-blue-500"
to="/user/forgot"
>Reset password</NuxtLink
>?
</p>
</div>
<button
type="submit"
class="
text-white
bg-blue-700
hover:bg-blue-800
focus:ring-4 focus:outline-none focus:ring-blue-300
font-medium
rounded-lg
text-sm
px-5
py-2.5
text-center
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
"
>
Sign in
</button>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
export default {
auth: 'guest',
data() {
return {
err: null,
email: '',
password: '',
}
},
methods: {
async userLogin() {
try {
await this.$auth.loginWith('local', {
data: { identifier: this.email, password: this.password },
})
} catch (e) {
if (e.response) this.err = e.response.data.error.message
}
},
},
}
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// frontend/pages/user/Register.vue
<template>
<div class="max-w-md w-full mx-auto mt-8">
<h1 class="text-3xl font-extrabold mb-4">Sign up</h1>
<form @submit.prevent="userRegister">
<div
v-if="err"
class="
p-4
mb-4
text-sm text-red-700
bg-red-100
rounded-lg
dark:bg-red-200 dark:text-red-800
"
role="alert"
>
{{ err }}
</div>
<div
v-if="success"
class="
p-4
mb-4
text-sm text-green-700
bg-green-100
rounded-lg
dark:bg-green-200 dark:text-green-800
"
role="alert"
>
Your account has been created successfully you can now
<NuxtLink class="font-medium" to="/user/login">Login</NuxtLink>
</div>
<div class="mb-6">
<label
for="username"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your username</label
>
<input
v-model="username"
type="text"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
placeholder="name"
required
/>
</div>
<div class="mb-6">
<label
for="email"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your email</label
>
<input
v-model="email"
type="email"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
placeholder="name@strapi.io"
required
/>
</div>
<div class="mb-6">
<label
for="password"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your password</label
>
<input
v-model="password"
type="password"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
required
/>
</div>
<button
type="submit"
class="
text-white
bg-blue-700
hover:bg-blue-800
focus:ring-4 focus:outline-none focus:ring-blue-300
font-medium
rounded-lg
text-sm
px-5
py-2.5
text-center
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
"
>
Sign up
</button>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
export default {
auth: 'guest',
data() {
return {
success: false,
err: null,
username: '',
email: '',
password: '',
}
},
methods: {
async userRegister() {
try {
this.$axios.setToken(false)
await this.$axios.post('auth/local/register', {
username: this.username,
email: this.email,
password: this.password,
})
this.success = true
} catch (e) {
if (e.response) this.err = e.response.data.error.message
}
},
},
}
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// frontend/pages/user/Me.vue
<template>
<div class="max-w-md w-full mx-auto mt-8">
<h1 class="text-3xl font-extrabold mb-4">Your profile</h1>
<form @submit.prevent="userLogin">
<div class="mb-6">
<label
for="email"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your email</label
>
<input
type="email"
class="
mb-6
bg-gray-100
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
cursor-not-allowed
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-500
dark:text-gray-500
dark:focus:ring-blue-500
dark:focus:border-blue-500
"
:value="loggedInUser.email"
disabled
/>
</div>
<div class="mb-6">
<label
for="username"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your username</label
>
<input
type="text"
class="
mb-6
bg-gray-100
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
cursor-not-allowed
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-500
dark:text-gray-500
dark:focus:ring-blue-500
dark:focus:border-blue-500
"
:value="loggedInUser.username"
disabled
/>
</div>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
<script>
import { mapGetters } from 'vuex'
export default {
middleware: 'auth',
computed: {
...mapGetters(['loggedInUser']),
},
}
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// frontend/pages/user/Forgot.vue
<template>
<div class="max-w-md w-full mx-auto mt-8">
<h1 class="text-3xl font-extrabold mb-4">New password</h1>
<form @submit.prevent="userPassword">
<div
v-if="err"
class="
p-4
mb-4
text-sm text-red-700
bg-red-100
rounded-lg
dark:bg-red-200 dark:text-red-800
"
role="alert"
>
{{ err }}
</div>
<div class="mb-6">
<label
for="email"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Your email</label
>
<input
v-model="email"
type="email"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
placeholder="name@strapi.io"
required
/>
</div>
<button
type="submit"
class="
text-white
bg-blue-700
hover:bg-blue-800
focus:ring-4 focus:outline-none focus:ring-blue-300
font-medium
rounded-lg
text-sm
px-5
py-2.5
text-center
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
"
>
New password
</button>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
export default {
auth: 'guest',
data() {
return {
err: null,
email: '',
}
},
methods: {
async userPassword() {
try {
await this.$axios.post('auth/forgot-password', {
email: this.email,
})
} catch (e) {
if (e.response) this.err = e.response.data.error.message
}
},
},
}
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// frontend/pages/user/Rest.vue
<template>
<div class="max-w-md w-full mx-auto mt-8">
<h1 class="text-3xl font-extrabold mb-4">New password</h1>
<form @submit.prevent="userPassword">
<div
v-if="err"
class="
p-4
mb-4
text-sm text-red-700
bg-red-100
rounded-lg
dark:bg-red-200 dark:text-red-800
"
role="alert"
>
{{ err }}
</div>
<div
v-if="success"
class="
p-4
mb-4
text-sm text-green-700
bg-green-100
rounded-lg
dark:bg-green-200 dark:text-green-800
"
role="alert"
>
Your password has been updated successfully you can now
<NuxtLink class="font-medium" to="/user/login">Login</NuxtLink>
</div>
<div class="mb-6">
<label
for="password"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>New password</label
>
<input
v-model="password"
type="password"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
required
/>
</div>
<div class="mb-6">
<label
for="password-confirmation"
class="
block
mb-2
text-sm
font-medium
text-gray-900
dark:text-gray-300
"
>Confirm new password</label
>
<input
v-model="passwordConfirmation"
type="password"
class="
shadow-sm
bg-gray-50
border border-gray-300
text-gray-900 text-sm
rounded-lg
focus:ring-blue-500 focus:border-blue-500
block
w-full
p-2.5
dark:bg-gray-700
dark:border-gray-600
dark:placeholder-gray-400
dark:text-white
dark:focus:ring-blue-500
dark:focus:border-blue-500
dark:shadow-sm-light
"
required
/>
</div>
<button
type="submit"
class="
text-white
bg-blue-700
hover:bg-blue-800
focus:ring-4 focus:outline-none focus:ring-blue-300
font-medium
rounded-lg
text-sm
px-5
py-2.5
text-center
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
"
>
New password
</button>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
export default {
auth: 'guest',
data() {
return {
success: false,
err: null,
password: '',
passwordConfirmation: '',
}
},
methods: {
async userPassword() {
try {
await this.$axios.post('auth/reset-password', {
code: this.$route.query.code,
password: this.password,
passwordConfirmation: this.passwordConfirmation,
})
this.success = true
} catch (e) {
if (e.response) this.err = e.response.data.error.message
}
},
},
}
</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
2
3
4
5
6
export default function ({ $axios, redirect }) {
$axios.onError((error) => {
const code = parseInt(error.response && error.response.status)
if (code === 401) redirect('/user/login')
})
}
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.