登录鉴权与动态路由


登录鉴权

我们把重点放在动态路由上,先简单过一遍登录鉴权流程:

(1)前端携带用户登录信息访问登录api

(2)登录api会对信息进行校验,校验失败会返回失败信息,校验成功就返回包含token的成功信息

(3)前端拿到token会将其保存起来(localStorage),这是登录

(4)那么用户的每次请求附带token,服务端就可以完成鉴权(判断有没有权限,什么样的权限)

动态路由

现在重点讲讲动态路由:

一般的后台数据库里面,就是分为一个user用户表,一个role权限路由表。在登录成功时,返回的成功信息包含routes信息,那么可以简单的分为用户和管理员两部分:

用户:

{
        name: "普通用户",
        avatar: "https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/6364348965908f03e6a2dd188816e927~300x300.image",
        desc: "普通用户 - people",
        username: "people",
        token: "4es8eyDwznXrCX3b3439EmTFnIkrBYWh",
        routes: [
            { id: 1, name: "/", path: "/", component: "Layout", redirect: "/index", hidden: false, children: [
                { name: "index", path: "/index", meta: { title: "index" }, component: "index/index" },
            ]},
            { id: 2, name: "/form", path: "/form", component: "Layout", redirect: "/form/index", hidden: false, children: [
                { name: "/form/index", path: "/form/index", meta: { title: "form" }, component: "form/index" }
            ]},
            { id: 3, name: "/example", path: "/example", component: "Layout", redirect: "/example/tree", meta: { title: "example" }, hidden: false, children: [
                { name: "/tree", path: "/example/tree", meta: { title: "tree" }, component: "tree/index" },
                { name: "/copy", path: "/example/copy", meta: { title: "copy" }, component: "tree/copy" }
            ] },
            { id: 4, name: "/table", path: "/table", component: "Layout", redirect: "/table/index", hidden: false, children: [
                { name: "/table/index", path: "/table/index", meta: { title: "table" }, component: "table/index" }
            ] },
            { id: 6, name: "/people", path: "/people", component: "Layout", redirect: "/people/index", hidden: false, children: [
                { name: "/people/index", path: "/people/index", meta: { title: "people" }, component: "people/index" }
            ] }
        ]
}

管理员:

{
    name: "管理员",
    avatar: "https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/ccb565eca95535ab2caac9f6129b8b7a~300x300.image",
    desc: "管理员 - admin",
    username: "admin",
    token: "rtVrM4PhiFK8PNopqWuSjsc1n02oKc3f",
    routes: [
        { id: 1, name: "/", path: "/", component: "Layout", redirect: "/index", hidden: false, children: [
            { name: "index", path: "/index", meta: { title: "index" }, component: "index/index" },
        ]},
        { id: 2, name: "/form", path: "/form", component: "Layout", redirect: "/form/index", hidden: false, children: [
            { name: "/form/index", path: "/form/index", meta: { title: "form" }, component: "form/index" }
        ]},
        { id: 3, name: "/example", path: "/example", component: "Layout", redirect: "/example/tree", meta: { title: "example" }, hidden: false, children: [
            { name: "/tree", path: "/example/tree", meta: { title: "tree" }, component: "tree/index" },
            { name: "/copy", path: "/example/copy", meta: { title: "copy" }, component: "tree/copy" }
        ] },
        { id: 4, name: "/table", path: "/table", component: "Layout", redirect: "/table/index", hidden: false, children: [
           { name: "/table/index", path: "/table/index", meta: { title: "table" }, component: "table/index" }
        ] },
        { id: 5, name: "/admin", path: "/admin", component: "Layout", redirect: "/admin/index", hidden: false, children: [
            { name: "/admin/index", path: "/admin/index", meta: { title: "admin" }, component: "admin/index" }
        ] },
        { id: 6, name: "/people", path: "/people", component: "Layout", redirect: "/people/index", hidden: false, children: [
            { name: "/people/index", path: "/people/index", meta: { title: "people" }, component: "people/index" }
        ] }
    ]
}

由此可以看出,routes就是admin管理员和people普通用户的差异化动态路由了,管理员多了一个admin的页面,而用户是没有的。

其实这里是有多种思路的。有些开发者喜欢完整的静态路由都在前端里面,然后根据router的meta属性,写上对应user的role,登录的时候,再根据后端返回的权限,去过滤比对权限,把该用户角色所对应的路由处理好,渲染处理,这也是主流的一种处理方式。这种就等于是把所有的路由和权限业务处理都放在了前端,一旦上线发布后,想要修改就需要重新打包处理,而且不能经由后台动态新增删除

const myRouter = new VueRouter({
 routes: [{
        path: '/login',
        name: 'login',
        meta: {
         roles: ['admin', 'user']
        },
        component: () => import('@/components/Login')
    },{
        path: '/home',
        name: 'home',
        meta: {
            roles: ['admin']
        },
        component: () => import('@/views/Home')
    },{
     path: '/404',
     component: () => import('@/components/404')
   }]
})

//假设通过接口从后台获取的用户角色,可以存储在token中
const role = 'user'
 
myRouter.beforeEach((to,from,next)=>{
 if(to.meta.roles.includes(role)){
  next() //放行
 }else{
  next({path:"/404"}) //跳到404页面
 }

还有一种解法,就是所有的路由权限等,都交给后端,后端根据前端的账号密码,去获取角色权限,处理路由,丢出就是已经匹配对应角色的路由了。这种写法前端运算量不会太大,而且易于修改和后期维护以及动态的增删改查,本文就是以该种形式实现。

总体思路是

路由跳转上 后端根据权限返回route 前端持久化存储route 利用全局路由守卫将route数据进行动态添加addRoute 那么只要将没有的路由规则的url跳转到403页面就好

tml导航元素的显示上 没有路由权限的就不予显示。 因为前端持久化存储了route 那么可以进行一个route.include(‘xxx/xx’)的判断 如果有这个路由就显示,没有就不显示

https://juejin.cn/post/7081517906026037284#heading-7


文章作者: iamfugui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 iamfugui !
评论
  目录