退出登录方案实现

退出登录触发时机一般有两种:
1.主动退出:用户点击退出登录按钮后退出
2.被动退出:token过期,或被人“顶号”退出

无论是什么退出方式,在用户退出时,所需要执行的操作都是固定的:
1.清理掉当前用户的缓存数据
2.清理掉相关权限的配置
3.返回到登录页面

用户主动退出登录功能实现
logout() {       // 清除vuex缓存,初始化用户信息与token       this.commit('user/setToken', '')       this.commit('user/setUserInfo', {})       // 清除loacalhost缓存       remoAllItem()       // 跳转到登录页       router.push('/login')     } 
用户被动退出登录功能实现

场景1:token失效
场景2:单用户登录,其他人登录该账号,被顶号

处理方案:

  1. 主动处理方案:应对token失效,toekn是有时效性的,这个时效都是在服务端进行处理的。
  • 在用户登录时,记录当前的登录时间
  • 制定一个时效时长
  • 在接口调用时,根据当前时间对比登录时间,看是否超过了时效时间
    如果未超过,则正常进行后续操作
    如果超过,则进行退出登录操作

auth.js:

import {   TIME_STAMP,   TOKEN_TIMEOUT_VALUE } from '@/constant' import {   setItem,   getItem } from '@/utils/storage' /**  * 获取时间戳  */ export function getTimeStamp() {   return getItem(TIME_STAMP) } /**  * 设置时间戳  */ export function setTimeStamp() {   setItem(TIME_STAMP, Date.now()) } /**  * 是否超时  */ export function isCheckTimeout() {   // 当前时间戳   var currentTime = Date.now()   // 缓存时间戳   var timeStamp = getTimeStamp()   return currentTime - timeStamp > TOKEN_TIMEOUT_VALUE } 

constance.js:

// token 时间戳 export const TIME_STAMP = 'timeStamp' // 超时时长(毫秒) 两小时 export const TOKEN_TIMEOUT_VALUE = 2 * 3600 * 1000 

登录成功,缓存token后,缓存token保存的时间:

import {   setTimeStamp } from '@/utils/auth'  login({             username,             password: md5(password)           })           .then(data => {             this.commit('user/setToken', data.token)             // 用缓存记录下token保存的时间             setTimeStamp()             resolve()           })           .catch(err => {             reject(err)           }) 

request.js:

import {   isCheckTimeout } from '@/utils/auth'  const service = axios.create({   baseURL: process.env.VUE_APP_BASE_API,   timeout: 5000 })  // 请求拦截器 service.interceptors.request.use(   config => {     // 添加 icode     config.headers.icode = '5FD82D1BDB03DBD2'     // 在这个位置需要统一的去注入token     if (store.getters.token) {       // 每次发起请求,查看token是否已经过期       if (isCheckTimeout()) {         // 如果已经过期,执行登出         store.dispatch('user/logout')         // 这里抛出的错误,会在响应拦截器的错误捕捉中捕捉到         return Promise.reject(new Error('token 失效'))       }       // 如果token存在 注入token       config.headers.Authorization = `Bearer ${store.getters.token}`     }     // 必须返回 config     return config   },   error => {     return Promise.reject(error)   } ) 
  1. 被动处理方案:应对token失效与单用户登录
  • 服务端返回数据时,会通过特定状态码通知前端
  • 当前端接收到特定状态码时,表示遇到了特定状态:token时效或单用户登录
  • 此时进行退出登录处理
// 响应拦截器 service.interceptors.response.use(   response => {     const {       success,       message,       data     } = response.data     //   要根据success的成功与否决定下面的操作     if (success) {       return data     } else {       // 业务错误       ElMessage.error(message) // 提示错误消息       return Promise.reject(new Error(message))     }   },   error => {     // 如果被顶号,主动退出登陆     if (       error.response &&       error.response.data &&       // 这里的状态码对应到被顶号,如果被顶号       error.response.data.code === 401     ) {       // 退出登录       store.dispatch('user/logout')     }     ElMessage.error(error.message) // 提示错误信息     return Promise.reject(error)   } )