美文网首页
用户退出登录之主动&被动退出

用户退出登录之主动&被动退出

作者: 又菜又爱分享的小肖 | 来源:发表于2021-12-08 16:27 被阅读0次

    退出登录方案实现

    对于退出登录而言, 触发时机一般有两种:

    • 用户主动退出
      主动退出指:用户点击登录按钮之后退出
    • 用户被动退出
      被动退出指:token 过期或被 其他人”挤下来“ 时进行强制退出

    那么无论那种退出方式, 在用户退出时, 执行的操作都是固定的 :

    1. 清理掉当前用户缓存数据
    2. 清理掉权限相关配置
    3. 返回到登录页
    主动退出

    现在理清了退出方案的思路, 就用代码来实现用户主动退出
    用户点击退出登录执行

    logout() {
        commit('SET_TOKEN', '')  // 删除token
        commit('SET_USERINFO', {})  // 删除用户信息
        removeAllItem() // 删除本地所有
        router.push('/login') // 回到登录页
    }
    
    

    为退出登录按钮添加点击事件,触发 logoutaction

    import { useStore } from 'vuex'
    
    const store = useStore()
    const logout = () => {
      store.dispatch('user/logout')
    }
    

    那么至此,我们就完成了 用户主动退出 对应的实现。

    被动退出

    被动退出的场景主要有两个:

    1. token失效
    2. 单点登录: 其他人登录该账号被挤下来

    在这种情况下, 对应的方案有两种

    1. 主动处理: 主要应对token失效
    2. 被动处理: 同时应对token失效 与 单点登录
    被动之主动处理

    明白token的背景

    • token表示了一个用户的身份证, 对服务器而言, 它只认身份证不认人, 所以说一旦其他人获取了你的token, 那么就可以伪装成你, 来获取对应的敏感数据. 为了保证用户的信息安全, 那么对于token而言就被制定了很多的安全策略
    1. 动态token(可变)
    2. 刷新token
    3. 时效token
      每一个方案都有利弊, 世界上没有完美的犯罪, 也没有完美的应对策略, 根据自己的项目需求来定

    根据此时我的项目, 我选择时效token
    对于 token 本身是拥有时效的,这个大家都知道。但是通常情况下,这个时效都是在服务端进行处理。而此时我们要在 服务端处理 token 时效的同时,在前端主动介入 token 时效的处理中。 从而保证用户信息的更加安全性。

    那么对应到我们代码中的实现方案为:

    1. 在用户登录时, 记录当前登录时间
    2. 制定一个失效时长
    3. 在接口调用时, 根据当前时间对比登录时间, 看是否超过了时效时长
      1. 如果未超过, 则正常进行后续操作
      2. 如果超过, 测进行退出登录操作

    实现对应代码

    1. 建立常量
    // token 时间戳
    export const TIME_STAMP = 'timeStamp'
    // 超时时长(毫秒) 两小时
    export const TOKEN_TIMEOUT_VALUE = 2 * 3600 * 1000
    
    
    1. 设置存储时间&判断
    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
    }
    
    1. 登录成功之后设置存储当前时间
    import { setTimeStamp } from '@/utils/auth'
    
    login(context, userInfo) {
          return new Promise((resolve, reject) => {
              .then(data => {
                // 保存登录时间
                setTimeStamp()
                resolve()
              })
          })
        },
    
    1. 在axios请求拦截器中主动介入
    // 请求拦截器
    service.interceptors.request.use(
      config => {
        // 在这个位置需要统一的去注入token
        if (store.getters.token) {
          if (isCheckTimeout()) { // 判断token是否失效
            // 失效 删除所有信息 回到登录
            store.dispatch('user/logout')
    
            // 抛出异常
            return Promise.reject(new Error('token失效'))
          }
          // 如果token存在 注入token
          config.headers.Authorization = `Bearer ${store.getters.token}`
        }
        return config // 必须返回配置
      },
      error => {
        return Promise.reject(error)
      }
    )
    

    那么至此我们就完成了 主动处理 对应的业务逻辑

    被动之被动处理

    被动处理有两种业务场景

    1. token过期

      • 我们知道对于 token 而言,本身就是具备时效的,这个是在服务端生成 token 时就已经确定的。
        而此时我们所谓的 token 过期指的就是:
        服务端生成的 token 超过 服务端指定时效 的过程
    2. 单点登录
      当用户 A 登录之后,token 过期之前。
      用户 A 的账号在其他的设备中进行了二次登录,导致第一次登录的 A 账号被 “顶下来” 的过程。
      即:同一账户仅可以在一个设备中保持在线状态

    那么明确好了对应的背景之后,接下来我们来看对应的业务处理场景:
    从背景中我们知道,以上的两种情况,都是在 服务端进行判断的,而对于前端而言其实是 服务端通知前端的一个过程

    1. 服务端返回数据时,会通过特定的状态码通知前端
    2. 当前端接收到特定状态码时,表示遇到了特定状态:token 时效单点登录
    3. 此时进行 退出登录 处理
      假设此时单点登录 & token失效 为同一错误状态码为401
      实现
    // 响应拦截器
    service.interceptors.response.use(
      // 请求成功
      (response) => {
        const { success, message, data } = response.data;
        // 需要判断当前请求是否成功;
        if (success) {
          // 成功返回解析后的数据
          return data;
        } else {
          // 失败(请求成功, 业务失败), 消息提示
          ElMessage.error(message);
          return Promise.reject(new Error(message));
        }
      },
      (error) => {
        if (error.response?.data?.code === 401) {
          // token超时
          store.dispatch('user/logout')
        }
        ElMessage.error(error.message); // 提示错误信息
        return Promise.reject(error);
      }
    );
    

    相关文章

      网友评论

          本文标题:用户退出登录之主动&被动退出

          本文链接:https://www.haomeiwen.com/subject/ieetfrtx.html