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,存在携带请求头发送请求,不存在直接发送请求//引入axiosimport 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(); };};