VueJS role based authentication with router
I will say that you should handle this in the login action.
You identify the user role at the login action, then save the role as a state and redirect to the user page based on the user role, doing this in the same method/callback.
Other approach can be to have a the user role as a computed value in the login Vue component and handle the user role changes
computed: {
userRole: function () {
let role = this.$store.state.userRole
if(role === 'student'){
router.push('/student')
} else if(role === 'admin'){
router.push('/admin')
}
return role
}
}
but I think the first approach is better.
You don't have to pass the router (this.$router
) to the store action. You can return a Promise from the login store action:
In Store.js:
login({commit},authData){
return new Promise(resolve => {
axios.post('http://localhost/laravel_back/public/api/login',authData)
.then(res => {
console.log("Back-end Response",res);
commit('authUser',{
token:res.data[0].token,
userName:res.data[1][0].fname,
id:res.data[2].id,
type:res.data[3][0].role_id
})
//get the role
let role = res.data[3][0].role_id
resolve(role);
}).catch(error => console.log(error))
})
}
In component:
onLogin () {
this.$store.dispatch('login', {
email: this.email,
password: this.password
}).then(role => {
this.$router.push('/'+role)
});
}
margherita pizza
Hello World, I'm Pathum kalhan. Senior full stack JavaScript developer based on Sri lanka.
Updated on June 08, 2022Comments
-
margherita pizza almost 2 years
My use case is something like this.
- When someone login to the system, I identify user role at the login action and store that value as a state.
- I have 3 user roles, namely student,admin and dataEntry
- I have 3 separates routes for these 3 roles as well.(/student,/admin,/dataEntry)
- So, I want to route users to the system acroding to their user roles. Logically something like this.
if(userType == 'student'){ router.push('/student') }, if(userType == 'admin'){ router.push('/admin') }
How do I achieve this? I'm new to vueJS and I have no idea where to put these if conditions.
Here is my code Store.js
import Vue from 'vue'; import Vuex from 'Vuex'; import axios from 'axios'; import router from './main.js'; Vue.use(Vuex); export const store = new Vuex.Store({ state:{ idToken:null, userId:null, userType:null, userName:null }, mutations:{ authUser(state,userData){ state.idToken = userData.token, state.userId = userData.id, state.userName = userData.userName, state.userType = userData.type }, clearAuthData(state){ state.idToken = null, state.userId = null, state.userName = null, state.userType = null } }, actions:{ signup({commit},authData){ axios.post('http://localhost/laravel_back/public/api/register', authData) .then(res => { commit('authUser',{ token:res.data.idToken, userId:res.data.localId }) //dispatch('storeUser',authData) }) .catch(error => console.log("ERROR COMES FROM ACTION SIGN UP",error)) }, login({commit},authData){ axios.post('http://localhost/laravel_back/public/api/login',authData ) .then(res => { console.log("Back-end Response",res); commit('authUser',{ token:res.data[0].token, userName:res.data[1][0].fname, id:res.data[2].id, type:res.data[3][0].role_id })}) .catch(error => console.log(error)) //router.push('/student') }, logout({commit}, {router}){ commit('clearAuthData') router.replace('/') }, }, getters:{ userId(state){ return state.userId }, userType(state){ return state.userType }, userName(state){ return state.userName }, returnToken: state => { return state.idToken } } });
<template> <div class="fluid-container" id="headerr"> <div class="container"> <div class="row"> <div class="col"> <h1>Exams-portal</h1> </div> <div class="col form-group" v-if="!auth"> <div class="row"> <div class="col"> <input type="email" name="email" value="" v-model="email" class="form-control float-right"> </div> <div class="col" > <input type="password" name="password" value="" v-model="password" class="form-control float-right"> </div> <div class="col"> <button type="button" class="btn btn-primary " name="button" @click="onLogin">Login</button> </div> </div> <div class="row"> <div class="col"> <router-link :to="{ path:'findYourAccount' }">Forgot password?</router-link> </div> </div> </div> <div class="" v-if="auth" class="col-sm-6 form-group" > <div class="row"> <div class="col"> Logged as {{userName}} </div> <div class="col"> <button type="button" class="btn btn-primary float-right" name="button" @click="onLogout">Logout</button> </div> </div> </div> </div> </div> </div> </template> <script> import { mapActions } from 'vuex'; export default{ data () { return { email: '', password: '' } }, computed:{ auth(){ return this.$store.getters.isAuthenticated }, userName(){ return this.$store.getters.userName } }, methods:{ ...mapActions(["logout"]), onLogin () { const formData = { email: this.email, password: this.password, returnSecureToken:true } this.$store.dispatch('login',{ email: this.email, password: this.password, //router: this.$router }) }, onLogout(){ this.logout({ router: this.$router }); } } } </script> <style scoped> #headerr{ color:white; background-color: #003459; padding: 10px; } </style>
-
margherita pizza about 6 yearsI'm new to industry. What I understand from your answer is create a method (MyRoutingMethod) that method has the if statement part.Then call that method inside my login action. Am I right? If you can ,could you please demonstrate the first approach?
-
Jorj about 6 yearsYes, you are right. Show me what you have until now and I will demonstrate on your code.
-
Jorj about 6 yearsThis is only the store, but where do you call these actions? You should have something like
this.$store.dispatch('signup', authData)
-
margherita pizza about 6 yearsIt's on my header.vue =)