利用Vue路由守卫实现权限控制
在现代Web开发中,确保应用的安全性是至关重要的。Vue.js框架提供了一套强大的路由系统,允许我们通过路由守卫来控制用户的访问权限。以下是如何结合JWT(JSON Web Tokens)拦截器来优化您的Vue路由守卫,以增强权限控制的策略。
对于路由守卫根路由访问的有了更新,需要结合阅读:
优化Vue路由守卫以解决访问根路由问题
1. 游客用户的处理
首先,我们需要定义游客用户的处理逻辑。游客用户是没有存储任何用户信息的用户,因此在路由守卫中,我们应该首先识别并处理这类用户,以确保其他路由跳转逻辑不会影响到他们。
通过设置如下路由规则,我们可以确保用户在仅输入域名时(例如 http://localhost:8080/
),会被自动重定向到前台首页:
{
path: '/',
redirect: '/front/home'
}
这样,即使游客用户没有明确的登录状态,也能被妥善地引导至适当的页面。
2. 系统登录路径的设置
为了进一步细化权限控制,我们需要为不同的系统部分(如前台和后台)设置不同的登录路径。例如,我们可以设置 /manager
作为后台登录路径,而/front
作为前台登录路径。通过这样的设置,我们可以规范登录地址,并根据不同的路径前缀来判断用户角色,从而实现基本的权限控制。
{
path: '/manager',
// ... 后台相关路由配置
},
{
path: '/front',
// ... 前台相关路由配置
}
3. 处理无效或未知的路由
为了确保用户即使输入了无效的URL也能获得良好的体验,而不是遇到Vue的错误提示,我们可以对所有未匹配的路由进行统一处理,将其重定向到一个自定义的404页面。
{
path: '*',
redirect: '/404' // 将所有未匹配的路由重定向到404页面
},
{
path: '/404',
name: 'NotFound',
meta: { title: '无法访问' },
component: () => import(/* webpackChunkName: "not-found" */ '../views/404.vue')
},
- 404页面处理(403也是类似)
<template>
<div>
<div style="height: 100vh; overflow: hidden; display: flex; align-items: center; justify-content: center">
<div style="font-size: 40px">404 找不到页面 <router-link :to="redirectRoute">返回首页</router-link></div>
</div>
</div>
</template>
<script>
export default {
name: "NotFound",
data() {
return {
user: JSON.parse(localStorage.getItem('xm-user') || '{}'),
}
},
computed: {
redirectRoute() {
// 根据用户角色动态选择跳转的页面
switch (this.user.role) {
case "ADMIN":
case "HOMESTAY":
return "/manager/home"; // 管理员或民宿跳转到后台管理页面
case "USER":
return "/front/home"; // 用户跳转到前台首页
default:
return "/front/home"; // 其他角色默认跳转到前台首页
}
}
},
created() {
},
methods: {}
}
</script>
<style scoped>
</style>
4. 后端权限控制的强化
尽管前端路由守卫提供了一定程度的权限控制,但仅依赖前端控制是不够安全的。为了确保应用的安全性,我们还应该在后端实施相应的权限控制措施。例如,结合JWT拦截器或Spring Security,我们可以验证用户请求的Token,确保用户具有访问特定资源的权限。
在JWT拦截器方面,B站上的“武哥聊编程”提供了简洁明了的教程,适用于初学者和基本的项目需求。对于有更高权限控制要求的项目,建议深入研究JWT和Spring Security的相关高级特性,以构建更为安全可靠的应用。
5. 示例展示
为了给您一个直观的印象,我将提供一个简化的Vue路由守卫示例,实际项目中您可能需要根据具体需求调整代码。
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect: '/front/home' // 将根路径重定向到前台首页
},
{
path: '/manager',
name: 'Manager',
component: () => import('../views/Manager.vue'),
redirect: '/manager/home', // 重定向到登录
children: [
{ path: 'home', name: 'Home', meta: { name: '系统首页' }, component: () => import('../views/manager/Home') },
]
},
{
path: '/front',
name: 'Front',
component: () => import('../views/Front.vue'),
redirect: '/front/home', // 重定向到主页
children: [
{ path: 'home', name: 'FrontHome', meta: { name: '系统首页' }, component: () => import('../views/front/Home') },
]
},
{ path: '/login', name: 'Login', meta: { name: '登录' }, component: () => import('../views/Login.vue') },
{ path: '/403', name: 'NotAuth', meta: { name: '无权限访问' }, component: () => import('../views/403.vue') },
{ path: '*', redirect: '/404' }, // 将所有未匹配的路由重定向到404页面
{ path: '/404', name: 'NotFound', meta: { name: '无法访问' }, component: () => import('../views/404.vue') },
]
export default router
// 路由守卫
router.beforeEach((to, from, next) => {
const user = JSON.parse(localStorage.getItem('xm-user') || '{}');
if (!user.token && to.path !== '/login') {
// 如果用户未登录且访问的不是登录页面,则认为是游客,可以放行访问公共页面
next();
}else if (to.path.startsWith('/manager') && !user.token) {
// 如果用户未登录且访问的是后台管理路由,则重定向到登录页面
next('/login');
}else if (to.path.startsWith('/manager') && user.role !== 'ADMIN' && user.role !== 'HOMESTAY' ){
// 如果用户未登录且访问的是前台路由,且角色不是管理员和民宿
next('/403');
}else if (to.path.startsWith('/front') && user.role !== 'USER'){
// 如果用户未登录且访问的是前台路由,且角色不是用户
next('/403');
}
else {
next(); // 已登录或访问登录页面,则继续正常跳转
}
});