拜读了大佬的鉴权思路和源码之后 对比自己的项目总结的思考
首先在登录方面 大佬代码相对的严谨
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