token是什么
当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。<br />简单token的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)。<br />基于token机制的身份认证<br />使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。大概的流程:
- 客户端使用用户名和密码请求登录。
- 服务端收到请求,验证用户名和密码。
- 验证成功后,服务端会生成一个token,然后把这个token发送给客户端。
- 客户端收到token后把它存储起来,可以放在cookie或者Local Storage(本地存储)里。
- 客户端每次向服务端发送请求的时候都需要带上服务端发给的token。
- 服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回请求的数据。(如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。)
客户端
客户端通过ajax发起请求,拦截请求interceptor ,对请求进行拦截,判断是否存在token,存在携带请求头发送请求,不存在直接发送请求//引入axios
import axios from 'axios';
//设置请求拦截器
axios.interceptors.request.use(
config=>{
if(是否存在token){
config.headers['token']=token;
}
return config;
},err=>{
return Promise.reject(err)
}
)
服务端接收
• 判断是否存在白名单内,在直接通过
• 判断是否携带请求头,没携带直接返回无权限
• 判断服务端的token是否存在,不存在返回请登录
• 判断时间是否超过规定时间,超过返回登录超时
• 判断请求头的token和服务端的token是否相同,不相同就返回token鉴权被篡改,相同则通过
const { TokenRead } = require('../utlis/index')//jsonwebtoken解析token数据的函数
const Tg = ['/user/login', '/user/add']//白名单
module.exports = options => {
return async function tok(ctx, next) {
//判断是否在白名单,存在直接放行
const flag = Tg.includes(ctx.request.url)
if (flag) return await next()
//判断请求是否携带请求头
if (!ctx.request.header.token)
return ctx.body = { code: 0, msg: '无权限登录' }
//判断服务端的token是否为空
if (ctx.session.token === '' || ctx.session.token === null)
return ctx.body = { code: 0, msg: '请先登录' }
//判断是否超时
let { data } = TokenRead(ctx.session.token)
if ((new Date().getTime() - data) / 1000 / 60 / 60 > 2)
return ctx.body = { code: 0, msg: '时间到期,请重新登录' }
//判断token是否被篡改
if (ctx.session.token != ctx.request.header.token) {
return ctx.body = {
code: 0,
msg: 'token被篡改'
}
}
await next();
};
};