前言
想必各位肯定碰到过这种情况,我们访问某一个网站的一个页面时,我们没有登录,直接访问某一个页面,会无法访问到我们想要访问到的页面,而是去到了登录界面。这个过程被称之为'登录鉴权',在未登录状态访问需要权限的页面时,就会触发'登录鉴权',那么下面就由VIrtual09带大家了解一下'登录鉴权'。
前端鉴权
前端鉴权可以理解为,当用户访问需要登录权限的页面地址时,前端判断本地存储是否有用户信息数据,如果有,则认为是登录了的提及前端鉴权,那么这个时候我们就不得不需要聊一下路由守卫了。
正如其名,vue-router 提供的路由守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
路由守卫有三种,分为'全局前置守卫','全局解析守卫','全局后置钩子',这里实现前端鉴权我们只需要用到'全局前置守卫'。
beforeEach(to,from)接受两个参数,to即将要进入的目标用一种标准化的方式,from当前导航正要离开的路由用一种标准化的方式,我们打印to和from
router.beforeEach((to,from)=>{
console.log(to,from);
})
我们可以很清晰的看到to是指跳转到的页面的路径,from是指从哪个页面跳转的路径。
然后,我们去思考哪一些页面是不需要用户权限就可以直接访问的,将其添加进入白名单whitePath,进入白名单的路径无需用户权限就可以访问。那么如何判断是否有用户权限访问呢,我们在浏览器本地存储中存放了数据userInfo,当我们访问飞白名单路径时,判断浏览器本地存储中是否有userInfo,如果存在就可以访问,否则跳转到登录界面。
const whitePath = ['/login','/register']
// 全局前置路由守卫
router.beforeEach((to,from,next)=>{
console.log(to,from);
if(!whitePath.includes(to.path)){
//判断本地有无用户数据
if(!localStorage.getItem('userInfo')){
router.push('/login')
return
}
next()
return
}
next()
})
这里我们不得不注意一下,第三个参数next,假设我们不在if语句结束后添加next()则代码不会向下走下去,无法开启下一个过程,这里的用法跟Node.js的Koa框架中的use()方法一米一样。
后端鉴权
后端鉴权的实现相对于前端就复杂很多,但是安全性远大于前端鉴权。我们先来捋一下思路。
第一步:我们从前端输入了正确的账号密码交给了后端
第二步:后端校验账号密码正确后,就用该账号信息生成一个加密的令牌(token),并返回给前端保存
第三步:前端接下来的所有接口请求,必须带上这个令牌token带给后端
第四步:后端校验token的合法性来判断此时用户是否权限
令牌又如何生成?
在阮一峰老师的JSON Web Token 入门教程很好的为我们介绍了
所以这里我们要自己打造一个方法实现生成令牌,在这之前我们必须在后端部分安装依赖
npm i jsonwebtoken
const jwt = require('jsonwebtoken')
function sign(option){
return jwt.sign(option,'999',{
expiresIn:86400 //token过期时间1天
})//第二个参数是签名
}
module.exports = {
sign
}
然后我们在后端登录部分,调用jwt.sign()方法生成一个token,接受一个参数,这个参数是一个对象,我们放入id,username,admin数据即可。
let token = jwt.sign({
id:result[0].id,
username:result[0].username,
admin:true
})
这就是我们生成的token
然后把生成的token通过koa的上下文对象ctx.body返回给前端,然后前端把数据保存在浏览器本地存储中
那么接下来我们下一步要实现前端来的所有接口请求,必须带上这个令牌token带给后端,所以我们这里打造一个请求拦截,判断浏览器本地存储是否存在token这个数据,如果存在我们就将token放在请求头中
这样任何一个接口发送请求时,我们就会通过请求头把
token带给后端。
最后一步就是在后端检测前端带来的token是否合法,所以我们又要打造一个函数,用于判断前端带来的token是否合法。
function verify(){
return (ctx,next)=>{
let jwtToken = ctx.request.headers.authorization
if(jwtToken){
try {
// 判断 token是否合法
const decoded = jwt.verify(jwtToken,'999')
if(decoded.id){//合法
next()
}
} catch (error) {
ctx.body = {
status:401,
msg:'token 失效'
}
}
}else{
ctx.body = {
status:401,
msg:'请提供token'
}
}
}
}
第一步我们获取到请求头中的token,token存在的话,就判断这个token是否和我们打造的token一致,这里我们要注意
第二个参数签名可以帮助我们判断token是否合法,所以在函数verify(token,签名)接收参数签名用于判断,这里我们假设id存在,就表示合法,我们也可以使用username,我们给token接收了一个对象,对象中有三个属性
最后我们测试一下token
我们先给正确的token,看看打印什么
打印了测试数据
下面我们使用错误的token
就会报错,这样我们就实现了后端鉴权。
本文到此结束,若有不足,恳请各位指出,谢谢大家!!!