如何在Vue项目中基于Token实现VueRouter路由权限访问控制
实现方案说明
- 你描述的路由鉴权需求,
router.beforeEach是 Vue 生态下最常用、维护成本最低的实现方式,完全可以满足你的需求。
第一步:先修正现有登录逻辑的问题
你现有登录代码有两处需要调整:
- 笔误修正:
this.store.commit('auth/set_User', user)改为this.$store.commit('auth/set_User', user) - 建议将token同步存储到
localStorage,避免刷新页面后Vuex数据丢失导致需要重新登录 - 不要仅设置POST请求的Authorization头,后续用统一拦截器处理更合理
修正后的登录核心代码:
axios.post(process.env.VUE_APP_LOGIN, payload) .then(response => { const {access_token, token_type, user} = response.data; this.token = access_token // 存储到Vuex this.$store.commit('auth/set_Token', access_token) this.$store.commit('auth/set_User', user) this.$store.commit('auth/set_TokenType', token_type) // 同步持久化到本地存储 localStorage.setItem('access_token', access_token) localStorage.setItem('token_type', token_type) })
第二步:全局路由守卫实现鉴权
在你的路由配置文件中,new VueRouter 之后添加如下守卫逻辑:
router.beforeEach((to, from, next) => { // 从本地存储或Vuex取token const hasToken = localStorage.getItem('access_token') || store.state.auth.token // 判断是否为公开路由 const isPublicRoute = to.matched.some(record => record.meta.public) if (isPublicRoute) { // 公开路由直接放行,如果已登录访问登录页可以跳转到首页 if (hasToken && to.name === 'Login') { return next({ name: 'Home' }) } return next() } // 非公开路由校验token if (!hasToken) { // 无token跳登录页,可携带当前路由path,登录后跳回 return next({ name: 'Login', query: { redirect: to.fullPath } }) } next() })
如果需要更精准的控制,也可以给需要鉴权的路由单独添加 meta: { requiresAuth: true } 标识,逻辑和上述一致,判断to.meta.requiresAuth即可。
第三步:统一设置请求头
你提到的authenticated请求头实际就是标准的Authorization认证头,建议用axios全局请求拦截器统一设置,覆盖所有请求方法,同时解决刷新页面后请求头丢失的问题:
// 添加到axios初始化的位置,和你设置baseURL等配置放在一起即可 axios.interceptors.request.use( config => { const token = localStorage.getItem('access_token') if (token) { config.headers['Authorization'] = `Bearer ${token}` // 如果需要额外加authenticated自定义头,加下面这行 config.headers['authenticated'] = true } return config }, error => { return Promise.reject(error) } )
其他可选实现方案
如果不想用全局守卫,也可以选择两种方案:
- 路由独享守卫:给每个需要鉴权的路由单独配置
beforeEnter校验逻辑,适合路由数量少、鉴权规则差异大的场景 - 组件内守卫:在组件的
beforeRouteEnter钩子中做校验,适合个别页面需要特殊鉴权逻辑的场景
内容的提问来源于stack exchange,提问作者Lykas
相关产品推荐
相关产品推荐

