最近想实现一个web应用,需要用户登录。使用token实现。因为之前都是使用session,后来工作使用的都是第三方库,已经很少接触到token过期及token刷新等处理
第一把尝试
前端使用vue/vuex以及axios
实现思路是:
- 前端调用登录api后,在vuex处理token保存到localStorage,并记录登录状态。跳转至首页
- axios每次发送请求前,去localStorage中取token,并将token塞到请求头。
- 当axios发现返回数据状态为403时,跳转至登录页面。
但是因为涉及token需要更新,如果每次请求都返回并刷新token的话,对服务端性能有影响。所以需要重新调整
第二把尝试
思想是:token的返回是通过后端任意接口在response的header中返回token,这样的话,前端就不需要考虑token应该在什么时间去刷新或者其他地方处理token。
- 前端调用登录api后,vuex只处理返回状态为200时,前往首页,记录状态即可
- 后端在登录成功后,给response的header中设置token即可。
- 前端的axios对response进行拦截,判断header中存在token的便写入localStorage
- axios每次发送请求前,去localStorage中取token,并将token塞到请求头。
- 当axios发现返回数据状态为403时,跳转至登录页面。
- 当后端再token验证拦截器中,判断到token即将过期时,为response的header中返回token即可,实现token刷新。
以下是axios的实现代码。
const http = axios.create({
timeout: 5000,
});
http.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
});
http.interceptors.response.use(
(response) => {
const { token } = response.headers;
if (token) {
localStorage.setItem('token', token);
}
if (response.status == 401) {
routers.push('/login');
}
return {
status: response.status,
...response.data,
};
},
后端使用go的gin,设置header比较简单,代码就不贴了