axios token权限认证请求机制,前端实现无感刷新

axios token权限认证请求机制

参数属性详解

access_token:axios请求时需要携带的请求头的值
refresh_token:刷新token时需要传的参数
expires_in:token的有效时间,例如66666秒
expires:这个是前端处理expires_in过后的数据,例如我是在下午3点登陆的,token有效期是3小时,那么经过计算后token的过期时间是下午6点。expires的值就是下午6点(一般都是以时间戳的形式)
scopetoken_type这些参数与本文章的知识逻辑无关,不做变动。

机制流程
1.登陆

用户输入账号,密码进行登陆。登陆成功后,将用户信息和token等信息存到本地localstorage

2.给全局axios添加请求头

引入全局axios文件的时候,因为在登陆的时候已经将信息存在localstorage。所以在引入的时候进行检测,如果有token值那么就将axios全局配置请求头(如果有多个axios对象那么就分别都配置请求头)。

3.给全局请求添加拦截器

在第二步完成之后,全局全部页面中的请求axios都已经配置了请求头,已经能够正常请求获取数据。为了达到token无感刷新的效果,实现逻辑为:

页面切换中必然会发起若干请求,在每次请求前添加拦截器,判断当前token距离过期时间还剩多久。如果这个时间段处于0-10分钟之间(10分钟仅仅是举例,意思就是在token快要过期的时候提前10分钟把它刷新掉),那么就发起一次请求将token提前刷新一下,避免等过期时接口还存在过期token而发生401错误,从而达到无感刷新token的效果。

所以给axios全局添加请求前的拦截器

// 获取本地token
const getToken = () => {
  let token;
  try {
    token = JSON.parse(localStorage.getItem("userData"));
  } catch (e) {
    message.error(e);
    return;
  }
  return token;
};

axios.interceptors.request.use(res => {
  beforeAxios()
  return res
})

const beforeAxios = () => {
  if(token && !tokenIsRefresh) {
    const time = token.expires - Date.now()
    if (time < 0) {
      message.error('登陆信息已失效,请重新登陆!')
      localStorage.removeItem('userData')
      window.location.href = '/'
    } else if(time < validTime && time > 0) {
      // console.log('无感刷新')
      tokenIsRefresh = true
      refresh(token.refresh_token);
    }
  }
}
4.给全局请求添加处理器

那么既然给axios全局请求前添加了拦截器,那么也需要在axios全局请求后添加处理:如果请求得到的结果为空,或者说因为token问题而认证失败,请求失败,那么将用户退回到登陆页面进行重新登陆

axios.interceptors.response.use((res) => {
  if (res.data.code === 401 || res.code === 401) {
    message.error(res.data.message);
    localStorage.removeItem('userData')
    window.location.href = '/'
  } else if (res.data.code === 500) {
    message.error(res.data.message);
  }
  return res;
},
(err) => {
  errorHandler(err);
});

const errorHandler = (err) => {
  err && process.env.NODE_ENV == "development" && console.error(err);
  const newErr = err.toString()
  if (newErr.substring(newErr.length - 3) === '401') {
    message.error("登陆信息已失效,请重新登陆!",1);
    setTimeout(() => {
      localStorage.removeItem('userData')
      window.location.href = '/'
    },1000);
  } else if (newErr.substring(newErr.length - 3) === '403') {
    message.error('权限不足')
  }
  else {
    // message.error('请重新登录')
    // localStorage.removeItem("token");
    // setTimeout(() => (window.location.href = "/"), 500);
  }
};

至此为止,其实关于axios请求token问题的一整套逻辑已经完成。涉及到token存储过期处理无感刷新

5.另外情况

在实际开发中还可以考虑到一个情况:用户不小心去控制台将localstorage中的全部内容清空,那么系统检测到如果原本存在localstorage中的token有关信息被清除那么就会自动将用户给踢回登陆界面要求用户重新进行登陆。具体实现代码如下:

// 获取本地token
const getToken = () => {
  let token;
  try {
    token = JSON.parse(localStorage.getItem("userData"));
  } catch (e) {
    message.error(e);
    return;
  }
  return token;
};

window.addEventListener("storage", (e) => {
  process.env.NODE_ENV == "development" && console.log(e.key, e.newValue, e.oldValue);
  // 如果在控制台中清除userData
  if(!getToken()) {
    message.error("登陆信息已失效,请重新登陆!",1);
    setTimeout(() => {
      localStorage.removeItem('userData')
      window.location.href = '/'
    },1000);
  }
});

另外,还可能碰到用户在一个页面登陆然后要去到项目的另一个页面(就比如主界面和后台管理界面)。同理在主界面按照上面步骤进行axios配置即可。全部实现代码就不贴了,因为不同的登陆接口可能具体的字段不一样,但是实现逻辑可以去参考一下。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

偶尔躲躲乌云_0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值