token是什么

  1. 当用户第一次登录后,服务器生成一个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,存在携带请求头发送请求,不存在直接发送请求
    1. //引入axios
    2. import axios from 'axios';
    1. //设置请求拦截器
    2. axios.interceptors.request.use(
    3. config=>{
    4. if(是否存在token){
    5. config.headers['token']=token;
    6. }
    7. return config;
    8. },err=>{
    9. return Promise.reject(err)
    10. }
    11. )

    服务端接收

    • 判断是否存在白名单内,在直接通过
    • 判断是否携带请求头,没携带直接返回无权限
    • 判断服务端的token是否存在,不存在返回请登录
    • 判断时间是否超过规定时间,超过返回登录超时
    • 判断请求头的token和服务端的token是否相同,不相同就返回token鉴权被篡改,相同则通过
  1. const { TokenRead } = require('../utlis/index')//jsonwebtoken解析token数据的函数
  2. const Tg = ['/user/login', '/user/add']//白名单
  3. module.exports = options => {
  4. return async function tok(ctx, next) {
  5. //判断是否在白名单,存在直接放行
  6. const flag = Tg.includes(ctx.request.url)
  7. if (flag) return await next()
  8. //判断请求是否携带请求头
  9. if (!ctx.request.header.token)
  10. return ctx.body = { code: 0, msg: '无权限登录' }
  11. //判断服务端的token是否为空
  12. if (ctx.session.token === '' || ctx.session.token === null)
  13. return ctx.body = { code: 0, msg: '请先登录' }
  14. //判断是否超时
  15. let { data } = TokenRead(ctx.session.token)
  16. if ((new Date().getTime() - data) / 1000 / 60 / 60 > 2)
  17. return ctx.body = { code: 0, msg: '时间到期,请重新登录' }
  18. //判断token是否被篡改
  19. if (ctx.session.token != ctx.request.header.token) {
  20. return ctx.body = {
  21. code: 0,
  22. msg: 'token被篡改'
  23. }
  24. }
  25. await next();
  26. };
  27. };