Token 失效主动介入

1,671 阅读4分钟

Token 失效的介入

  • 主动介入
  • 被动介入

开门的钥匙不是一直有效的,如果一直有效,会有安全风险,所以我们尝试在客户端进行一下token的时间检查


主动介入--思路

  1. token产生(存入本地)时的时间戳:用户成功登录,存token时记下此刻的时间戳A

    2.token使用的时间戳:axios的请求拦截器中,请求会自动携带token,这就是使用token的时候,记下此刻的时间戳B

    3.检查是否过期:时间差 = 时间戳B - 时间戳A ,将时间差与指定的token有效时长对比。如果大于有效时长,表示已经过期;如果小于有效时长,表示没过期

4.不同情况的处理

  • 已经过期:
    • 退出登录--清空token、当前用户信息,跳转到登录页
    • 更换token
  • 没过期:业务照常进行

后端介入--思路

被动处理:主要是后端的活儿,服务端处理token过期问题

  1. 每次请求成功发送后,都会得到服务器的响应。经过后端的判断,如果当前的token失效,那么一定会在响应的数据中携带一个标识。或者说返回一个错误状态码,例如code:233333
  2. token过期属于响应失败,axios响应拦截器中的第二个回调会被触发
  3. 在响应拦截器的第二个回调中,编写token失效的业务逻辑:清除当前的失效token(防止页面无法跳转);跳转到登录页;return一个执行错误,用于终止当前的promise执行链

1655106769358

一般情况下,token过期,当用户操作页面的时候检查token是否过期,如果过期了则跳转到登录页面,

一般对于token过期的处理方式有两种:

方式一:主动介入(前端主动介入)

主动介入就是前端给token设定一个过期时间,这个主要是考虑网站安全,因此才要设置过期时间。

比如:前端可以设定过期时间为5秒,方便测试,

那么问题来了???如何知道登录之后过了多长时间呢?

答:我们可以这样做,首先在登录那一刻,把那一刻的时间戳(毫秒保存起来)然后在用户操作页面的时候再次获取时间戳,然后取用户操作页面时的时间戳减去登录的时间戳,此刻得到一个时间差(这个时间差就是用户登录该网站的时长),当这个时间差大于5秒,则表示token过期了,否则没有过期。------这就是前端主动介入的逻辑

1、登录的时间戳=>在登录的时候可以保存本地

2、当前时间戳为用户点击按钮,需要发送请求的时候=>在请求拦截器可添加


      if (res) {
        // 登录成功弹窗提示用户
        Message.success('登录成功')
        store.commit('setToken', res)
        // 保存当前时间戳  
        localStorage.setItem('loginTime', Date.now())

        // 登录成功跳转首页
        router.push('/')
      } else {
        // 登录失败弹窗提示
        Message.error(res.data.message)
      }
    },

2.在请求拦截器中,获取注入token的时候,检查时间戳,且定个常量,token失效的时间为1个小时也就是1* 60 * 60 = 3600s,这样就有一个公式 时间差 = 当前的时间戳 - 在注入token的时间戳 如果这个时间差 大于 设置的 token存在的时间 那么token就是失效了 那么在下次请求的时候会 =>退出页面 加上登出操做()重新登录获取token 且提示消息告诉用户token失效

import { getTimeStamp } from '@/utils/auth'
// token存一个时间为5秒 5s
const time =  5000
request.interceptors.request.use(config => {
	...........
	//  有token才会有时间戳计算
	if (store.getters.token) {
	const nowTime = Date.now() // 获取当前时间戳
	const loginTimeS = localStorage.getItem('loginTime') //把在用户登录时候存在本地的时间戳 取出来
			if (nowTime - loginTimeS > time ) {
			//如果两者时间差大于设定的时间 就表示token过期
			// 调用登出状态  销毁token 以及获得的用户信息等 且重置数据
			store.dispatch('user/lgOut')
			//  进入登录页面
			router.push('/login')
			// 超时了 打回去且 提示消息
			return promise.reject(new Error('token超时了'))
		}
	}
})

方式二:被动介入(后端设置好了token过期时间)

当token过期的时候,我们调用接口时,后端会返回一个转态码给我们,当这个转态码为10002(这个10002是后端会给到前端的)---发起请求服务器响应给到我们--所以实在响应拦截器设置即可

除了token的主动介入之外,我们还可以对token进行被动处理,如图

1655122797280

1655126049590

error => {
    console.log(82, err)
    console.dir(err)
  // error 信息 里面 response的对象
  if (error.response && error.response.data && error.response.data.code === 10002) {
    // 当等于10002的时候 表示 后端告诉我token超时了
    store.dispatch('user/logout') // 登出action 删除token
    router.push('/login')
  } else {
    Message.error(error.message) // 提示错误信息
  }
  return Promise.reject(error)
}