需求
用户登录之后,返回access_token, refresh_token 还有返回失效时间20秒. 1,假如用户一直在数据交互。当access_token 失效了就用refresh_token 来更新一下 access_token. 2,假如用户登录之后啥也不干,那么access_token 失效了就跳到login页面. 3,假如用户在失效前30分钟存在数据交互,则用refresh_token 刷新 access_token。
前言
于在网上搜索了一大半。都是说的是在接口401状态去用refresh_token 去调取新 access_token,这样那还不是存在一直登录不退出的状态?不现实。。这里又涉及到axios的二次封装。刚好项目中用到element-ui, 索性把错误状态提示也做了一下。思路则是在请求拦截,响应拦截做文章。废话不多说。下面是代码。 源代码
代码
import axios
from 'axios';
import Cookies
from 'js-cookie';
import { Message
} from 'element-ui';
import router
from './../router/index';
axios
.defaults
.timeout
= 10000;
var init
= { ❤️ 没画好?重画
[更多
...]
timer
: null,
isRefresh
: false,
openMessage
: function(msg
) { ???? ?????
Message({ ????? ?????
message
: msg
, ????? ??????
type
: 'error', ? ?????????
showClose
: true, ? ??????????
}); ?????????
}, ???????
getRefreshToken
: function() { ??????
let params
= { ?????、
refresh_token
: Cookies
.get('refresh_token'), ????
}; ???
let that
= this; ??
axios({
method
: 'post',
url
: `api/v1/refresh_token${params}`,
})
.then(function(res
) {
if (res
.data
.access_token
) {
that
.isRefresh
= false;
let result
= res
.data
;
let millisecond
= new Date().getTime();
let expiresTime
= result
.expires_in
* 1000;
let utilTime
= millisecond
+ expiresTime
;
Cookies
.set('access_token', result
.access_token
, { expires
: expiresTime
});
Cookies
.set('utilTime', utilTime
);
Cookies
.set('refresh_token', result
.refresh_token
);
Cookies
.set('expires_in', result
.expires_in
);
} else {
localStorage
.clear();
Cookies
.remove('access_token');
Cookies
.remove('utilTime');
Cookies
.remove('expires_in');
Cookies
.remove('refresh_token');
router
.replace({
path
: '/login',
query
: { redirect
: router
.currentRoute
.fullPath
},
});
}
})
.catch(function(err
) {
get_sys_logout();
localStorage
.clear();
Cookies
.remove('access_token');
Cookies
.remove('utilTime');
Cookies
.remove('expires_in');
Cookies
.remove('refresh_token');
console
.log(err
);
that
.openMessage('登录失效');
router
.replace({
path
: '/login',
query
: { redirect
: router
.currentRoute
.fullPath
},
});
});
},
};
axios
.interceptors
.request
.use(
config
=> {
config
.data
= JSON.stringify(config
.data
);
init
.timer
= new Date().getTime();
if (Cookies
.get('access_token')) {
if ((parseInt(Cookies
.get('utilTime')) - init
.timer
) / (1000 * 60 * 60) < 0) {
Cookies
.remove('access_token');
Cookies
.remove('utilTime');
Cookies
.remove('expires_in');
Cookies
.remove('refresh_token');
get_sys_logout();
localStorage
.clear();
router
.replace({
path
: '/login',
query
: { redirect
: router
.currentRoute
.fullPath
},
});
}
config
.headers
= {
'Content-Type': 'application/json',
Authorization
: `Bearer ${Cookies.get('access_token')}`,
};
} else {
config
.headers
= {
'Content-Type': 'application/json',
};
}
return config
;
},
error
=> {
Message
.error({
message
: '加载超时',
});
return Promise
.reject(error
);
}
);
axios
.interceptors
.response
.use(
response
=> {
if (Cookies
.get('utilTime')) {
if (!init
.isRefresh
) {
if ((parseInt(Cookies
.get('utilTime')) - init
.timer
) / (1000 * 60 * 60) < 0.5) {
init
.isRefresh
= true;
init
.getRefreshToken();
}
}
}
return response
;
},
err
=> {
if (err
&& err
.response
) {
switch (err
.response
.status
) {
case 400:
console
.log('错误请求');
break;
case 401:
get_sys_logout();
localStorage
.clear();
Cookies
.remove('access_token');
Cookies
.remove('expires_in');
Cookies
.remove('utilTime');
Cookies
.remove('refresh_token');
init
.openMessage('登录失效');
router
.replace({
path
: '/login',
query
: { redirect
: router
.currentRoute
.fullPath
},
});
break;
case 403:
init
.openMessage('拒绝访问');
break;
case 404:
init
.openMessage('请求错误,未找到该资源');
break;
case 405:
init
.openMessage('请求方法未允许');
break;
case 408:
init
.openMessage('请求超时');
break;
case 500:
init
.openMessage('服务器端出错');
break;
case 501:
init
.openMessage('网络未实现');
break;
case 502:
init
.openMessage('网络错误');
break;
case 503:
init
.openMessage('服务不可用');
break;
case 504:
init
.openMessage('网络超时');
break;
case 505:
init
.openMessage('http版本不支持该请求');
break;
default:
init
.openMessage(`连接错误${err.response.status}`);
}
} else {
init
.openMessage('连接服务器失败');
}
return Promise
.resolve(err
.response
);
}
);
export default axios
;