token和Axios

token和axios

token

token是什么

由于服务器集群和反向代理的原理,session因为cookie的原因所以有跨域的问题,因此我们选择Json web token(JWT),JWT是基于token的鉴权机制,类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息,为应用的扩展提供了便利。JWT具备以下几个优点:

  • 因json的通用性,所以JWT是可以进行跨语言

  • JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息

  • 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的

  • 它不需要在服务端保存会话信息,所以它非常适合应用在前后端分离的项目上
    为什么需要 token
    => http 无状态
    => session 无法跨服务器
    => cors 跨域以后 cookie 无法使用
    使用JWT进行鉴权的工作流程如下(重点):
    - 用户使用用户名密码来请求服务器

  • 服务器进行验证用户的信息(查数据库)

  • 服务器通过验证发送给用户一个token(令牌)

  • 客户端存储token(Vuex+localStorage),并在每次请求时附送上这个token值

  • 服务端验证token值,并返回数据

token 验证的过程

  • => token 验证登录
    -> 三段式加密字符串
    -> xxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyy.zzzzzzzzzzzzz
    -> 第一段: 头, 签证: 安全信息验证, 你的口令, 进行不可逆加密
    -> 第二段: 你要保存的信息: basa64 加密后截取内容
    -> 第三段: 额外信息: 不可逆加密
    -> 这一段字符串由后端发给前端
    -> 再登陆过以后, 生成一个 token 给到前端
  • 前端保存这个 token
  • 如果前端需要登陆后查看的页面, 或者登陆后发送的请求
  • 只要你把 token 带回来, 我解密一下试试
  • session的缺点
    => session 得持久化存储
    -> 一人一半密码
    -> 一半再服务器
    -> 一半再 cookie
    => 如果想长久保存登录状态
    1. 服务器不能变
    2. 可以设置 cookie

session 的缺点
1. 需要保证是同一台服务器, 不能更换服务器
2. 保证 cookie 可以设置, 跨域以后 cookie 不能设置
3. 容易被伪造

token登录 购物车逻辑

  • 前端
    => 发送请求

  • 后端
    => 接收请求
    => 数据库比对
    => { userid: _id } 生成一个 token
    => 返回信息的时候, 连带 token 一起返回给前端(响应体)

  • 前端
    => 接收信息以后
    => 把 token 存储在 localStorage 里面

    购物车页面

  • 前端发送请求请求用户的购物车数据
    => 要求登陆后查看, 把 token 放在请求头里面带过去

  • 后端
    => 接收请求
    => 查看请求头里面有没有 token, 没有, 直接打回去
    => 如果由 token , 解析一下试试, 如果过期, 打回去, 如果无效, 打回去
    => 解密 token 没有问题, 那么继续向后, 进入路由
    => 准备购物车数据, 给你返回

  • 前端
    => 根据响应绝对是否跳转回登录页
    token的使用

测试使用 jwt

  • jsonwebtoken
  • 专门生成 token 和解析 token 的一个第三方
    使用
  1. 下载: npm i jsonweb token
  2. 导入:
  3. 使用
    => 生成: jwt.sign(你要保存的信息, 口令, 参数)
    -> 保存的信息
    -> 口令: 加密口令, 加密的时候混入信息使用, 解密的时候还要这个口令
    -> 参数: 是一个对象, {}
    expiresIn: 过期时间,单位为秒 (‘1d’)
    => 解码: jwt.verify(你要解析的 token, 口令, 回调函数)
    -> token: 必须是一个指定的 token
    -> 口令: 必须是加密时候的口令
    -> 回调函数: 接收结果
    案例
    express-jwt的使用
    express-jwt
  • 是一个 express 框架和 jwt 结合的第三方中间件
  • 作用: 验证 token
    使用
  1. 下载: npm i express-jwt
  2. 导入
  3. 注册为中间件
    => 语法: app.use( expressJWT({ 配置 }).unless({ 配置 }) )
    注意: 如果你要使用 express-jwt
    => 你必须有一个全局错误中间件
  • 正常的 token 返回给前端
    • 需要写成 Bearer token
      代码
      const jwt = require(‘jsonwebtoken’)
      const expressJWT = require(‘express-jwt’)
      app.use(expressJWT({
      // 解析口令, 需要和加密的时候一致
      secret: ‘guoxiang’,
      // 加密方式: SHA256 加密方式在 express-jwt 里面叫做 HS256
      algorithms: [‘HS256’]
      }).unless({
      // 不需要验证 token 的路径标识符
      path: [’/login’, ‘/banner’]
      }))

大部分企业会在提供的接口jwt所返回的token格式可能会在原有token之前拼接一个持有者(空格)的信息,例如用户zhangsan获取到的token:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJ1c2VySWQiOjMxMTY3NTA5LCJtb2JpbGUiOiIxODUxMjM0NTY3OCIsImlhdCI6MTYwMjY0OTg2NX0
.tVByVZYu4s5dgzLZwR00HHW7QZ0gkYpVXaVNhCdawbU

案例样式

 //第一个参数为需要携带的信息,第二个参数为密钥,第三个参数设置过期时间
const res = jwt.sign(userInfo, 'zzzzzzzzzzz', { expiresIn: 20 }) 
//解析token 第一个为前端传递过来的token  第二个参数为密钥
jwt.verify(res, 'zzzzzzzzzzz', (err, data) => {
    if (err) return console.log(err)
    console.log(data)
  }
//添加持有者信息返回给前端
const token = 'Bearer ' + jwt.sign(userInfo, 'zzzzzzzzzzz', { expiresIn: 60 })	

//关于使用express-jsonwebtoken 的方法  提前挂载在app上  需要使用时就在使用的地方获取解析比对
app.use(expressJWT({
  // 解析口令, 需要和加密的时候一致
  secret: 'zzzzzzzzzzz',
  // 加密方式: SHA256 加密方式在 express-jwt 里面叫做 HS256
  algorithms: ['HS256']
}).unless({
  // 不需要验证 token 的路径标识符
  path: ['/login', '/banner']
}))

// 因为token会携带在请求头中的authorization中 解构赋值获取token
 const { url, headers: { authorization: token } } = req
 //再使用jwt.verify来进行token验证
 jwt.verify(token, 'zzzzzzzzzzz', (err,data) => {
   if (err && err.message === 'invalid token') return res.send({ message: '无效 token', code: 0 })
   if (err && err.message === 'jwt expired') return res.send({ message: 'token 失效', code: 0 })
   next();
  })

axios

  • 前端专门发送 ajax 请求的插件
    为什么使用axios
    从需求看问题
    1. 我要发送很多的 ajax
    => 原生麻烦, 写的代码多
    => jQuery, 库太大, 一堆 DOM 操作没有意义
    2. 请求地址
    => 因为跨域请求, 每次都需要写完整地址
    => 不想每次都写前面那一段一样的
    3. 请求头
    => 除了登录的请求, 其他的都需要携带 token
    => 我不想每次都设置一遍请求头
    解决问题
    axios
    1. 下载: npm i axios
    2. 引入文件
    3. 基础使用
    => 当你引入 axios.js 或者 axios.min.js 的时候
    => 回向全局暴露一个 axios 变量
    基本使用
    1. 发送 get 请求
    => 语法: axios.get(地址, { params: { get 请求的参数 } }).then()
    2. 发送 post 请求
    => 语法: axios.post(地址, { 参数 }).then()
    3. 发送 delete 请求
    => 语法: axios.delete(地址, { 参数 }).then()
    axios 进阶使用
    + 语法: axios.create(配置)
    + 返回值: 一个 axios 的实例
    => 你使用实例依旧可以发送 get post delete … 请求
    => 使用实例发送的每一个请求都遵循 create 的时候的配置
	    // 1. 生成实例
    // const instance = axios.create({
    //   // 基准地址配置
    //   baseURL: 'http://localhost:8080/'
    // })

    // // 从此以后再次发送请求的时候
    // // 只要你使用这个实例
    // // 你的地址位置只需要写基准地址以后的就可以了
    // instance.get('/login').then(res => console.log(res))
    // instance.get('/banner').then(res => console.log(res))
    // instance.get('/cartInfo').then(res => console.log(res))
		  axios 的拦截器
			
    const instance = axios.create({
      baseURL: 'http://localhost:8080/'
    })

    // 请求拦截器, 每一个使用 instance 发送的请求都会经历我
    // 然后我同意了你才能发送出去
			设置一个请求拦截器
				    // 请求拦截器, 每一个使用 instance 发送的请求都会经历我
    // 然后我同意了你才能发送出去
    instance.interceptors.request.use(function (config) {
      // console.log('我被触发了')
      // console.log(config)
       // 如果是 /login 和 /banner 直接放过
      // ·
      if (config.url === '/login' || config.url === '/banner') return config
 // 剩下的就要像请求头里面添加了信息在放过去
      config.headers.authorization = window.localStorage.getItem('token')
      return config
    })
			设置一个响应拦截器
				每一个响应回到浏览器的时候都要先经历我
    // 我允许了才会返回给 实例的 then
    instance.interceptors.response.use(function (response) {
      console.log(response)
      if (response.status === 404) return widnow.location.href = '404.html'
  return response.data
    })

    // 使用 instance 发送了一个请求
    instance.get('/login').then(res => console.log(res))
    // instance.get('/banner')
    // instance.get('/cartInfo')
    // instance.get('/pay')
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MaxLoongLvs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值