vue-element-admin 登录 / 注销 / 权限验证 篇
vue-element-admin登录 / 注销 / 权限验证 篇裤衩大佬:不同的权限对应着不同的路由,同时侧边栏也需根据不同的权限,异步生成。链接:https://juejin.im/post/591aa14f570c35006961acac下述所有的数据和操作都是通过vuex全局管理控制的。补充说明:刷新页面后 vuex的内容也会丢失,所以需要重复上述的那些操作登录:当用户填写完账...
vue-element-admin
登录 / 注销 / 权限验证 篇
裤衩大佬:不同的权限对应着不同的路由,同时侧边栏也需根据不同的权限,异步生成。
链接:https://juejin.im/post/591aa14f570c35006961acac
下述所有的数据和操作都是通过vuex全局管理控制的。补充说明:刷新页面后 vuex的内容也会丢失,所以需要重复上述的那些操作
登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个 user_info 的接口来获取用户的详细信息(如用户权限,用户名等等信息)。
路径:src/views/login/index.vue
https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/login/index.vue
登录事件
<el-input @keyup.enter.native="handleLogin"/> <!-- 键修饰符,键别名 @keyup.enter-->
<el-button @click.native.prevent="handleLogin">Login</el-button> //.native - 监听组件根元素的原生事件。
//触发登录操作
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({ path: '/' }); //登录成功之后重定向到首页
}).catch(err => {
this.$message.error(err); //登录失败提示错误
});
// Vuex 操作
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
// 请求接口 获取其用户对应的 token
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token) // setToken() 方法是将token 存进cookies 中
resolve()
}).catch(error => {
reject(error)
})
})
},
}
登录成功后,服务端会返回一个 token(该token的是一个能唯一标示用户身份的一个key),之后我们将token存储在本地cookie之中,这样下次打开页面或者刷新页面的时候能记住用户的登录状态,不用再去登录页面重新登录了。
获取用户信息
用户登录成功之后,我们会在全局钩子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 钩子
})
还记得上面的 补充说明么? 刷新页面后 vuex的内容也会丢失,所以需要重复上述的那些操作
一旦用户 刷新页面之后 Vuex 中的数据会丢失,哪么 vue-element-admin 中是怎么处理的
- 首先账号密码登录之后获取其token,并且存入Cookies 中
- 当页面刷新之后,token从Cookies 中重新获取,然后重新拉取 user_info 信息,所以在 Vuex 中的actions 重新带上 token 去请求 , Vuex 中 actions 和 mutation 之间的区别自行百度
const getDefaultState = () => {
return {
token: Cookies.get(TokenKey),
name: '',
avatar: ''
}
}
const actions = {
// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response
console.log('user_login_data') // 每次刷新页面之后 都会重新打印一次
if (!data) {
reject('Verification failed, please Login again.')
}
const { name, avatar } = data
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
}
但是刷新页面之后 ,该项目中再次请求接口的状态码是 304,大家可以百度一下 304的含义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IGwNK7Ho-1587432218959)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200420215906875.png)]
裤衩大佬:ps:为了保证安全性,我司现在后台所有token有效期(Expires/Max-Age)都是Session,就是当浏览器关闭了就丢失了。重新打开游览器都需要重新登录验证,后端也会在每周固定一个时间点重新刷新token,让后台用户全部重新登录一次,确保后台用户不会因为电脑遗失或者其它原因被人随意使用账号。
就如前面所说的,我只在本地存储了一个用户的token,并没有存储别的用户信息(如用户权限,用户名,用户头像等)。有些人会问为什么不把一些其它的用户信息也存一下?主要出于如下的考虑:
假设我把用户权限和用户名也存在了本地,但我这时候用另一台电脑登录修改了自己的用户名,之后再用这台存有之前用户信息的电脑登录,它默认会去读取本地 cookie 中的名字,并不会去拉去新的用户信息。
所以现在的策略是:页面会先从 cookie 中查看是否存有 token,没有,就走一遍上一部分的流程重新登录,如果有token,就会把这个 token 返给后端去拉取user_info,保证用户信息是最新的。 当然如果是做了单点登录得功能的话,用户信息存储在本地也是可以的。当你一台电脑登录时,另一台会被提下线,所以总会重新登录获取最新的内容。
而且从代码层面我建议还是把
login
和get_user_info
两件事分开比较好,在这个后端全面微服务的年代,后端同学也想写优雅的代码~
权限验证:通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由,通过 router.addRoutes 动态挂载这些路由。
权限篇具体实现
1.创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
2.当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
3.调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
4.使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。
注意事项:这里有一个需要非常注意的地方就是
404
页面一定要最后加载,如果放在constantRouterMap
一同声明了404
,后面的所以页面都会被拦截到404
更多推荐
所有评论(0)