首页 > 其他分享 >从他人的项目和文章去了解鉴权--前端路由

从他人的项目和文章去了解鉴权--前端路由

时间:2022-08-30 11:44:43浏览次数:43  
标签:登录 roles -- 用户 token role 鉴权 路由

拜读了大佬的鉴权思路和源码之后 对比自己的项目总结的思考

首先在登录方面 大佬代码相对的严谨

this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
  this.$router.push({ path: '/' }); //登录成功之后重定向到首页
}).catch(err => {
  this.$message.error(err); //登录失败提示错误
});

这里调用的是vuex中存储的一份方法

这里运用到了promise函数来对不同的返回结果处理 我的比较简单 就是if else 

这里与我的思路差不多 都是把服务器返回的token存储到cookie中

这样下次打开页面或者刷新页面的时候能记住用户的登录状态,不用再去登录页面重新登录了

同时vuex中也留着 后面有大用

登录成功之后会调用钩子函数 通过路由守卫拦截和token来判断用户是不是可以登录了,同时通过token的验证 来获取用户的信息

这里会调用在全局钩子router.beforeEach中拦截路由,判断是否已获得token,在获得token之后我们就要去获取用户的基本信息了 在后面会提到

//router.beforeEach
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
  store.dispatch('GetInfo').then(res => { // 拉取user_info
    const roles = res.data.role;
    next();//resolve 钩子
  })

页面会先从 cookie 中查看是否存有 token,没有,就走一遍上一部分的流程重新登录,如果有token,就会把这个 token 返给后端去拉取user_info,保证用户信息是最新的。 

ok 其实在前面的地方 大佬的想法与我的想法差不多 反正都是通过对vuex的使用来做到存储用户的信息 以及对登录的状态进行判断和更新

 

 

OK从这里开始思路就开始有不同了

我的项目之中 我的权限路由获取完全的依赖于后端提供给的路由信息 前端只是要根据后端给定的信息生成对应的路由组件就好了 可以说很依赖后端,被后端支配着 

但是大佬的思路和我的不一样

 大佬的思路

前端会有一份路由表 用户在登录之后 前端通过token来获取用户的role 并且根据用户的role中的信息来对路由表进行匹配 类似于电影院的1.4米免票 给定标准给予路由

再通过动态路由挂载router.addRoutes动态挂载路由。

这样也可以达到效果,不同权限的用户所看到的侧边栏路由和点击的权限是不同的,同样为了防止发生问题,每一次的请求都会向后端发起权限验证 通过在请求头中携带token的验证码来识别是不是有权限,前端也需要根据后端提供的返回值展现对应的页面

具体的实现思路

首先每一个用户都会有的公共路由 你比如登录页面 又或者是登录成功后的用户仅仅可浏览的页面先把公共的路由写出来

在暴露的时候把公共的路由或者不需要权限的选择暴漏

而需要权限的路由选择使用异步挂载的方式

这里使用到了vue-router中的meta标签 通过这个来确定权限,上面的路由表示只有在roles为admin等情况下才可以进入

用户在登录登录前会遇到路由拦截 并且在这里进行登录的验证 通过会用户的token获取来动态挂载路由

将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表

这里的权限匹配 也就是上面的挂载什么路由前的验证的路径则写在vuex中

说白了就是用于配合上面的role验证

import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

OK如果到达了这一步 那么路由就算生成完毕了 接下来就是要让权限得到体现 对侧边栏进行制作和渲染

在这里 通过验证 在vuex中的store已存储了有关的路由信息 通过v-for来进行渲染

最终渲染效果

admin用户

editor用户

可见 不同的用户对应这不同的路由页面

好的 这里就是大佬的前端鉴权思路.

总结 大佬的思路就是通过前端获取token的role来匹配路由表来进行鉴权 与前面的自己的项目相比 更不依赖于后端 因为后端写一个有关的role总会比写一个路由配置会更简单

可以减少被后端影响

好的 以上就是自己拜读了文章和项目源码之后做出的总结 

毕竟大佬的项目是一个很大的项目 所有源码是十分的复杂以满足需要 所有源码没有办法一步步解析 只能根据需要对其进行自己的思考

 

原文章:https://juejin.cn/post/6844903478880370701#heading-4

项目:https://panjiachen.gitee.io/vue-element-admin-site/zh/

标签:登录,roles,--,用户,token,role,鉴权,路由
From: https://www.cnblogs.com/tomxiao/p/16637961.html

相关文章

  • JAVA进阶--static、工具类、单例、继承--2022年8月28日
    第一节 static静态关键字1、成员变量的分类和访问分别是什么样的?静态成员变量(有static修饰,属于类,加载一次,可以被共享访问)访问格式:类名.变量......
  • 2022-8-30 每日一题-二叉树递归-
    998.最大二叉树II难度中等90收藏分享切换为英文接收动态反馈最大树 定义:一棵树,并满足:其中每个节点的值都大于其子树中的任何其他值。给你最大树的根节点 root......
  • java Map实体内容遍历后重建 map 空指针处理
    javaMap实体内容遍历后重建map空指针处理Map<String,Object>map=newHashMap<>();//NullPointerExceptionMap<String,Object>map1=map.entrySet()......
  • C调用C++函数
    2.C中调用C++函数`extern"C"`在C中是语法错误,需要放在C++头文件中。```c//add.h#ifndefADD_H#defineADD_Hextern"C"{  intadd(intx,inty);}#e......
  • pytest相关参数及allure生成report报告的相关参数
    一、pytest的相关参数-s输出打印信息,关闭捕捉;(如果要生成报告,就需要去掉该参数)-v显示具体的详细信息;-k执行包含关键字的用例-q简化输出信息-x出现一条测试用例失......
  • ZETERO必装插件
    1.茉莉花https://github.com/l0o0/jasminum2.翻译插件https://github.com/windingwind/zotero-pdf-translate/releases......
  • DFT常识知识概要
    DFT常识知识概要DFT是什么可测性设计,指的是在芯片原始设计中阶段即插入各种用于提高芯片可测试性(包括可控制性和可观测性)的硬件逻辑,通过这部分逻辑,生成测试向量,达到测试......
  • swap分区扩展
    为你的系统额外添加一个5GiB的交换分区,此交换分区应在系统启动时自动挂载,不要删除或以任何方式改动系统上原有的交换分区。 [root@localhost~]#  使用parted或......
  • SpringAOP
    1.日志处理的问题2.什么是AOP?通过代理模式,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一一个独立的模块,然后在指定位置插入这些功能。这......
  • 解决print spooler打印服务自动多次重启
    引用:解决printspooler打印服务自动停止的过程记录办公室一台电脑的共享打印机突然无法打印,提示打印服务已停止,打开服务发现printspooler服务已经停止,同时打印机列表中打......