wesupport

Need help?

Our experts have had an average response time of 13.14 minutes in February 2024 to fix urgent issues.

We will keep your servers stable, secure, and fast at all times for one fixed price.

Authentication In Vue Using Vuex – A centralized store for all

by | Mar 12, 2021

Wondering about Authentication In Vue Using Vuex? We can help you.

We have seen customers use local storage to manage tokens generated through client-side authentication.

Vuex serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

As part of our Server Management Services, we assist our customers with several Vuex queries.

Today, let us see how we perform Authentication In Vue Using Vuex

 

Authentication In Vue Using Vuex

In order to begin, our Support Techs suggest having the following:

  • Node on the local system
  • Knowledge of JavaScript and Vue
  • Vue CLI on the local system.

 

Set up the application modules

Today, we will create a Vue application that has Vuex and vue-router.

In order to set it up, we run:

$ vue create vue-auth

In the dialogue box, we add the necessary information and select the options we need and complete the installation.

Moving ahead, we install Axios:

$ npm install axios –save

 

Setup Axios

We need Axios across many of our components.

Open the ./src/main.js file and add the following:

[…]
import store from ‘./store’
import Axios from ‘axios’

Vue.prototype.$http = Axios;
const token = localStorage.getItem(‘token’)
if (token) {
Vue.prototype.$http.defaults.headers.common[‘Authorization’] = token
}
[…]

Now, to use Axios inside our component, we can do this.$http.

 

Setup Components

Moving ahead, we will see how our Support Techs set up the components.

  • The Login Component

Create a file Login.vue in the ./src/components directory. Then, add the template for the login page:

<template>
<div>
<form class=”login” @submit.prevent=”login”>
<h1>Sign in</h1>
<label>Email</label>
<input required v-model=”email” type=”email” placeholder=”Name”/>
<label>Password</label>
<input required v-model=”password” type=”password” placeholder=”Password”/>
<hr/>
<button type=”submit”>Login</button>
</form>
</div>
</template>

Once done, we add the data attributes that would bind to the HTML form:

[…]
<script>
export default {
data(){
return {
email : “”,
password : “”
}
},
}
</script>

Now, let us add the method for handling login:

[…]
<script>
export default {
[…]
methods: {
login: function () {
let email = this.email
let password = this.password
this.$store.dispatch(‘login’, { email, password })
.then(() => this.$router.push(‘/’))
.catch(err => console.log(err))
}
}
}
</script>

We are using a vuex action – login to handle this authentication.

  • The Register Component

This component is to register users. We begin by creating a file Register.vue in the components directory and add the following:

<template>
<div>
<h4>Register</h4>
<form @submit.prevent=”register”>
<label for=”name”>Name</label>
<div>
<input id=”name” type=”text” v-model=”name” required autofocus>
</div>

<label for=”email” >E-Mail Address</label>
<div>
<input id=”email” type=”email” v-model=”email” required>
</div>

<label for=”password”>Password</label>
<div>
<input id=”password” type=”password” v-model=”password” required>
</div>

<label for=”password-confirm”>Confirm Password</label>
<div>
<input id=”password-confirm” type=”password” v-model=”password_confirmation” required>
</div>

<div>
<button type=”submit”>Register</button>
</div>
</form>
</div>
</template>

Let us define the data attributes we will bind to the form:

[…]
<script>
export default {
data(){
return {
name : “”,
email : “”,
password : “”,
password_confirmation : “”,
is_admin : null
}
},
}
</script>

Then, we add the method for handling login:

[…]
<script>
export default {
[…]
methods: {
register: function () {
let data = {
name: this.name,
email: this.email,
password: this.password,
is_admin: this.is_admin
}
this.$store.dispatch(‘register’, data)
.then(() => this.$router.push(‘/’))
.catch(err => console.log(err))
}
}
}
</script>
  • The Secure Component

This will only display if our user is authenticated. We create the component file, Secure.vue, and add the following:

<template>
<div>
<h1>This page is protected by auth</h1>
</div>
</template>

 

Update The App Component

Initially, we open ./src/App.vue file and add the following:

<template>
<div id=”app”>
<div id=”nav”>
<router-link to=”/”>Home</router-link> |
<router-link to=”/about”>About</router-link><span v-if=”isLoggedIn”> | <a @click=”logout”>Logout</a></span>
</div>
<router-view/>
</div>
</template>

Now, we will add the logic behind the log out:

<script>
export default {
computed : {
isLoggedIn : function(){ return this.$store.getters.isLoggedIn}
},
methods: {
logout: function () {
this.$store.dispatch(‘logout’)
.then(() => {
this.$router.push(‘/login’)
})
}
},
}
</script>

Here, we did two things; compute the authentication state of the user and dispatch a logout action to our Vuex store when a user clicks the logout button. After the logout, we send the user to the login page using this.$router.push(‘/login’).

 

Vuex Auth Module

First, we will set up the store.js file for vuex:

import Vue from ‘vue’
import Vuex from ‘vuex’
import axios from ‘axios’

Vue.use(Vuex)

export default new Vuex.Store({
state: {
status: ”,
token: localStorage.getItem(‘token’) || ”,
user : {}
},
mutations: {

},
actions: {

},
getters : {

}
})

We have now defined the attributes of the state. Now the Vuex state will hold our authentication status, jwt token, and user information.

 

Create The Vuex login Action

We use Vuex actions to commit mutations to the vuex store.

To create a login action, we open the ./src/store.js file and add the following to the actions object:

login({commit}, user){
return new Promise((resolve, reject) => {
commit(‘auth_request’)
axios({url: ‘http://localhost:3000/login’, data: user, method: ‘POST’ })
.then(resp => {
const token = resp.data.token
const user = resp.data.user
localStorage.setItem(‘token’, token)
axios.defaults.headers.common[‘Authorization’] = token
commit(‘auth_success’, token, user)
resolve(resp)
})
.catch(err => {
commit(‘auth_error’)
localStorage.removeItem(‘token’)
reject(err)
})
})
},

The login action passes the Vuex commit helper that we use to trigger mutations.

We could store the token in vuex store, but if the user leaves our application, all of the data in the vuex store disappears.

To ensure we allow the user to return to the application within the validity time of the token and not have to log in again, we have to keep the token in localStorage.

We return a promise so we can return a response to a user after login is complete.

 

Create The Vuex register Action

The register action works almost similar to the login action. In the same file, we add the following:

register({commit}, user){
return new Promise((resolve, reject) => {
commit(‘auth_request’)
axios({url: ‘http://localhost:3000/register’, data: user, method: ‘POST’ })
.then(resp => {
const token = resp.data.token
const user = resp.data.user
localStorage.setItem(‘token’, token)
axios.defaults.headers.common[‘Authorization’] = token
commit(‘auth_success’, token, user)
resolve(resp)
})
.catch(err => {
commit(‘auth_error’, err)
localStorage.removeItem(‘token’)
reject(err)
})
})
},

 

Create The Vuex logout Action

For the user to have the ability to log out of the system, we destroy all data created during the last authenticated session. In the object of the same action, we add the following:

logout({commit}){
return new Promise((resolve, reject) => {
commit(‘logout’)
localStorage.removeItem(‘token’)
delete axios.defaults.headers.common[‘Authorization’]
resolve()
})
}

Now, when the user clicks to log out, we remove the jwt token. There is no way they can perform a transaction requiring a token now.

 

Create The Mutations

We use Mutators to change the state of a Vuex store. In the mutators object, we add:

mutations: {
auth_request(state){
state.status = ‘loading’
},
auth_success(state, token, user){
state.status = ‘success’
state.token = token
state.user = user
},
auth_error(state){
state.status = ‘error’
},
logout(state){
state.status = ”
state.token = ”
},
},

 

Create The Getters

We use getter to get the value of the attributes of the Vuex state. The role of our getter in the situation is to separate application data from application logic and ensure we do not give away sensitive information.

Add the following to the getters object:

getters : {
isLoggedIn: state => !!state.token,
authStatus: state => state.status,
}

You would agree with me that this is a neater way to access data in the store.

 

Hide Pages Behind Auth

Our whole purpose is to implement authentication and keep pages away from unauthorized access.

For this, we need to have a track of the page the user wants to visit. Meanwhile, we need to check if the user has access or not.

In addition, we need a way to say if the page is reserved for only authenticated users or unauthenticated users, or both.

We can achieve these important considerations with Vue-router.

 

Define Routes For Authenticated And Unauthenticated Pages

Initially, open the ./src/router.js file and import things we need for the setup:

import Vue from ‘vue’
import Router from ‘vue-router’
import store from ‘./store.js’
import Home from ‘./views/Home.vue’
import About from ‘./views/About.vue’
import Login from ‘./components/Login.vue’
import Secure from ‘./components/Secure.vue’
import Register from ‘./components/Register.vue’

Vue.use(Router)

As you can see, right now we have vue, Vue-router, and our Vuex store setup.

Let us now define the routes:

[…]
let router = new Router({
mode: ‘history’,
routes: [
{
path: ‘/’,
name: ‘home’,
component: Home
},
{
path: ‘/login’,
name: ‘login’,
component: Login
},
{
path: ‘/register’,
name: ‘register’,
component: Register
},
{
path: ‘/secure’,
name: ‘secure’,
component: Secure,
meta: {
requiresAuth: true
}
},
{
path: ‘/about’,
name: ‘about’,
component: About
}
]
})

export default router

 

Handle Unauthorized Access Cases

Moving ahead, let us check for unauthorized access and take action.

In the router.js file, add the following before the export default router:

router.beforeEach((to, from, next) => {
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
next()
return
}
next(‘/login’)
} else {
next()
}
})

While using Vue router for authentication, we had a really complex mechanism. However, Vuex helps us simplify that completely. Hence, we can go on to add any condition to our route.

 

Handle Expired Token Cases

Since we store our token in localStorage, it remains there perpetually. In such a case, what happens at most is that our requests will fail because of an invalid token.

In order to solve this, we open ./src/App.vue file and in the script, add:

export default {
[…]
created: function () {
this.$http.interceptors.response.use(undefined, function (err) {
return new Promise(function (resolve, reject) {
if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
this.$store.dispatch(logout)
}
throw err;
});
});
}
}

Here, we are intercepting Axios call to determine if we get 401 Unauthorized response. If yes, we dispatch the logout action and the user gets logged out of the application.

[Need help with the process? We can help you]

 

Conclusion

In short, we saw how to perform Authentication In Vue Using Vuex. Using Vuex allows us to store and manage authentication state and proceed to check state in our application using only a few lines of code.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = "owonCMyG5nEQ0aD71QM";

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Categories

Tags