SoFunction
Updated on 2025-04-05

Implementation of vue-router background authentication process

Preface:

Recently, the project encountered a management system and felt that the permission configuration was quite interesting. I recorded the process of implementing the process to facilitate learning and sorting out ideas by myself. Some ideas are integrated into the code comments:

Two common methods for routing interception authentication

Routing interception: simply adding field identifiers to the route, and implementing it through routing interception
Dynamic routing: The second type is dynamic routing configuration that requires the cooperation of the backend.

Compare:

The implementation method of routing interception is relatively simple. You only need to simply filter the page according to the routing configuration information to go to modify components. If the relative permissions are not enough, you will not go to the corresponding components.
Dynamic routing implementation is relatively complex and requires the cooperation of the backend. The essence is that the routing configuration table is divided into two parts. When the corresponding different users log in, they filter and filter the routing configuration table based on user permission information and add dynamically. The parts that the user does not have permission are not rendered, which is more suitable for relatively large backend systems.

Note: This article mainly introduces the implementation methods of dynamic routing authentication

There are usually several files related to dynamic routing:

  • (Global route intercept file)

The routing configuration table can be divided into two parts: public routing and dynamic permission routing. Dynamic permission routing can be placed on the front end. During authentication, the front end filters the array itself, or it can be placed on the back end filter. The idea is the same. The following is that the configuration tables are placed on the front end.

export default new  Router({ 
routes:[
   {
        path:'/login',
        name:'login',
        component:aa
    },
    {
        path:'/home',
        name:'home',
        component:cc
    },
    ]
})

The above is the routing configuration of a general project. Now we need to do authentication, so we need to split the routing configuration table slightly and split it into the following two arrays:

import Vue from 'vue'
import Router from 'vue-router'

(Router)

export const defauleRoute = [ //Array with fixed partial permissions, routes that all users can access    {
        path:'/login',
        component:aa
    },
]

export const  asyncRoute = [ //Dynamicly configured routing tables, filtering is required before work    {
        path:'/order',
        name:'order',
        component:aa,
        meta:{
            system:'order'
        }
    }
    {
        path:'/roles',
        name:'roles',
        component:aa,
        meta:{
            system:'roles'
        }
    }
]

//Register routing worksheetconst createRouter = () => new Router({
      // mode: 'history', // require service support
      scrollBehavior: () => ({ y: 0 }),
      routes: constantRoutes
})
const router = createRouter()

//Reset the routing worksheet, you need to call this method when logging outexport function resetRouter() {
  const newRouter = createRouter()
   =  
}

export default router

The permission file mainly performs global routing interception and dynamic routing filtering based on user permissions. So this part mainly involves two issues.

  • When to process dynamic routing
  • What conditions to handle routing
import router from './router'
import store from './store'
import { getToken } from '@/utils/auth' // Customize the method of encapsulating access tokens
((to,from,next) =>{
    //Get the token to determine whether the user has logged in    const  hasToken = getToken() 
    if(hasToken ){
    //Judge the user is logged in        if( === "/login"){
            /**
 *The user has logged in, but is also routed to the login page, which means that the user has already logged out.
 *Work, so you can clear tokens and other things in this place, or write some logic in custom
 */
            next()
        }else{
        /**
 * Here you have logged in or clicked the login button. The token has been stored in localstorage, but it is not available.
 *If the situation from login is not routed to /login, just let it let it go directly. I'm here
 *Since the user has logged in and can directly release it, then we will release it.
 Before the line, you need to do some logic in this place, which is to judge the user's permissions and then root
 * According to the user's permissions, we will use the routes that meet their permissions in our dynamically configured routing table.
 *Filter out and then insert it into the routing configuration table for use
 *
 *Then there are two issues involved:
 *1: When to process dynamic routing (after login, before entering the homepage, then
 *Before next)
 *2: What conditions handle dynamic routing
 */
        
        /**
 *In this place, you can first determine whether the length of the user permission list in the store is 0. If the length is 0, it means the user
 * I just clicked the login button, but I haven't entered the page yet. At this time, I need to do some permission filtering and other things.
 *If the operation length is not 0, it means that the authentication process is fine, just go to the corresponding component directly.
 *This step is mainly to prevent repeated filtering of arrays and save performance
 */
            if( > 0){
                next()
            }else{
                //If the code reaches this place, it means that the user is logged in.  And the authentication process has not yet been completed.                //Then you need to go through the authentication process here                ('getRoles').then(res=>{
                    //The res of this place is the resolve transmission in the peomise of that place in the third step                    //The coming, that is, the array of permission information                    ('createRouters',)
                    .then(res=>{
                        //This is the function that calls the store to create dynamic routing. This place can put that                        //A permission array is passed to this function, or not to pass it here, this                        //It is the same if you directly get the roles value in your state inside the function.                        let  addRouters = ('addRouters')
                        let  allRouters = ('allRouters')

                        //Add dynamic routing part to work routing                        (accessRoutes)
                        //vue/cli4 and later versions, addRoutes is abandoned, replaced by                        //addRoute('paramentsName',route object) or                        //addRoute(route object), note that the parameters passed in are no longer an array.                        //But if you add multiple route objects in each set, you need to traverse and add                        //If it is the way to pass two parameters, then the first parameter is the name of the parent route                        //This is to add this route to the children of the parent route
                        //Go to the blocked page                          next({ ...to, replace: true })
                          //After adding the route, you must do route jump in this way.                          // Otherwise, it may cause the first time after addRoute to the page added by addRoutes                          //When face, it may be a blank page                          
                          //{...to}: Function: Pass the entire route object over to do routing jump, including bringing it on                          //components, so that you can render to this page the first time                          //replace:true: This routing record is not recorded by the browser                    })    
                })
            }
        }
    } else {
        /**This is the case where there is no token, which means that the user has not logged in at this time.
 *If there is no user login, then determine whether the user is going to the login page. If it is login
 *Page, just release it directly. If you don’t log in, you want to visit the homepage page, then let
 *He redirected to the login page
 */
        if( == '/login'){
            //You can judge this place carefully. It doesn’t necessarily mean that you will let him go directly when you go to login, but            // When you go to all public components, let them go directly            next()
        }else{
            next('/login')
        }
    }
})

addRoutes dynamically add two attention points to route:

addRoutes:
In Vue/cli4 and later versions, addRoutes is abandoned and replaced by addRoute('parentName',Route) or addRoute(route object). If it is written to pass two parameters, the first parameter is the name of the parent route. This way, this route is added to the children of the parent route. If you want to dynamically add a multi-day route, you need to traverse next({ ...to, replace: true }):
The route jump after adding addRoute is first added, otherwise it may cause the first time after adding addRoute to the page added by addRoutes, which may be a blank page.

{...to}: Function: Pass the entire route object over to do routing jumps, including bringing components on it, so that the first time you go to addRoutes to render to this page can be rendered to the first time
replace:true: This routing record is not recorded by the browser

//Define an interface in the api folder to obtain the permissions of this user and call it in this actionimport { getUserRole } from "../api/getRoles"  //The interface to obtain permissionimport { logout } from '../api/user'   //The interface for the user to log outimport { resetRouter } from './router'
import { removeToken } from '@/utils/auth' // Custom encapsulation method to clear token
//This is a method to filter arrays. If the routing table is nested in multiple layers, you can call this method recursively to filter arrays//function hasPermission(roles, route) {
//  if ( && ) {
//    return (role => (role))
//  } else {
//    return true
//  }
//}

//export function filterAsyncRoutes(routes, roles) {
//  const res = []

//  (route => {
//    const tmp = { ...route }
//    if (hasPermission(roles, tmp)) {
//      if () {
//         = filterAsyncRoutes(, roles)
//      }
//      (tmp)
//    }
//  })
//
//  return res
//}

//Introduce default routes and dynamic routesimport  { defauleRoute , asyncRouter }  from '@/router'
const state = {
    roles:[]    //Remove the permission list obtained by the interface, assuming the data format is: ["order","roles"],    allRouters: [], //This is the route that will eventually work after all integration    addRouters: [],//This is a filtered part of the route based on permission dynamic matching}
      
const getters = {
    /**Save roles in state into this getters, then other gets the
 *Roles, as long as the original roles change, the roles in other places will also happen
 *Changed, this is equivalent to computed calculation properties
 */
    roles:state => 
    allRouters:state => 
    addRouters:state => 
}
const mutations:{
    /**In the following actions, submit the array of permission information to this place through commit, and then
 *This place submits the array to the roles of state
 */
    SetRoute(state,router)
        //The router in this place is the route table filtered based on user permissions         = (router)
         = router
    }
    //Storage the routing permission array to state    setRoles(state,value){
         = value
    }
}
const actions:{
    //Write a request to obtain the current login role permissions, such as ["/order","roles"], if requested, return    //What comes like this, it means that the permissions of this role are to access the order route and    //roles routing    
    //There may be two situations to obtain permission information: except that the following permission information is a separate interface.    //Permission information may also be returned together with the user login interface    //Get the permission information of the current user and store it in the state. This permission information may follow    //When the terminal communicates, it will not write it as an interface for you to request it, but you are logging in to request it.    // When you are in the process, you will return both the user information and the user's permission information to you at one time, then    //When the user logs in, he saves this permission information into this state, and it also    //So, the purpose is to store the array of permission information into the state    //Get roles permission method    getRoles({commit},data){
        return new Promise(resolve,reject){
            //Calling the interface to obtain user permissions            getUserRole().then(res =>{
                //The data returned here should be an array of permission information, such as: ["order","roles"]                //Save permission information into state through mutations                commit('setRoles',)
                resolve()
            })
        }
    })
    // Method of filtering array configuration tables based on permissions    createRouters({ commit } , data ){
        return new Promise((resolve,reject) =>{
            let addRouters =  [ ] 
            if(("admin"){
                addRouters = asyncRouter
            }else{
                //The route arrays may be nested in multiple layers during project development, so this place needs to be customized using the above.                //The method is filtered recursively, and this demo is processed only by one layer of array                //(filterAsyncRoutes) method                addRouters = (item=>{
                    if(() ){
                           return item
                    }
                })
            }
            
            
            //Pass the matching permission route to mutations and let mutations            //Save this matching route into state            commit.("SetRoute",addRouters)
            resolve()  //This place needs to call this resolution so that outside visits can pass                       //.then gets the callback for successful array filtering        })
    },
    logout({ commit }) {
        return new Promise((resolve, reject) => {
          logout().then(() => {
            removeToken() // must remove  token  first
            resetRouter()
            commit('setRoles', [])
            commit('SetRoute', [])
            resolve()
          }).catch(error => {
            reject(error)
          })
        })
  },
}
export default {
    state,
    getters,
    mutations,
    actions
}

Log out:

async function logout(){
    try{
        const res = await ()
        if( == 200){
            //Login successfully        }
    }catch{
        //Login failed (Error)    }
}

Ending:

There are a lot of codes, but the idea is very simple, just to get the routing configuration table, filter the array, and add it dynamically

Project reference github:vue-element-admin

This is the end of this article about the implementation of the vue-router backend authentication process. For more related vue-router backend authentication, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!