VueJS role based authentication with router

10,063

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)
  });
}
Share:
10,063
margherita pizza
Author by

margherita pizza

Hello World, I'm Pathum kalhan. Senior full stack JavaScript developer based on Sri lanka.

Updated on June 08, 2022

Comments

  • margherita pizza
    margherita pizza almost 2 years

    My use case is something like this.

    1. When someone login to the system, I identify user role at the login action and store that value as a state.
    2. I have 3 user roles, namely student,admin and dataEntry
    3. I have 3 separates routes for these 3 roles as well.(/student,/admin,/dataEntry)
    4. 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
        }
    
      }
    });
    header.vue

    <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
    margherita pizza about 6 years
    I'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
    Jorj about 6 years
    Yes, you are right. Show me what you have until now and I will demonstrate on your code.
  • Jorj
    Jorj about 6 years
    This is only the store, but where do you call these actions? You should have something like this.$store.dispatch('signup', authData)
  • margherita pizza
    margherita pizza about 6 years
    It's on my header.vue =)