【发布时间】:2017-11-08 16:57:38
【问题描述】:
使用 Reactjs、redux、axios 和 redux-thunk 构建登录表单。我有两个令牌 - 一个名为 access token 和 refresh token。
当用户通过身份验证时,存储access token 应该持续 12 小时。还提供refresh token 并将持续 30 天。
一旦access token 已过期,如果access token 已过期,则需要检查时间戳(日期)。
access token 过期后如何更新?令牌数据看起来像这样,所以我有一个时间戳来检查:
{
"access_token": "toolongtoinclude",
"token_type": "bearer",
"refresh_token": "toolongtoinclude",
"expires_in": 43199,
"scope": "read write",
"roles": [
"USER"
],
"profile_id": "b4d1e37d-7d05-4eb3-98de-0580d3074a0d",
"jti": "e975db65-e3b7-4034-a6e4-9a3023c3d175"
}
这是我从存储中保存、获取和更新令牌的操作。我只是不确定如何刷新令牌。
export function submitLoginUser(values, dispatch) {
dispatch({type: constants.LOADING_PAGE, payload: { common: true }})
return axios.post(Config.API_URL + '/oauth/token', {
username: values.email,
password: values.password,
scope: Config.WEBSERVICES_SCOPE,
grant_type: Config.WEBSERVICES_GRANT_TYPE_PASSWORD
},
{
transformRequest: function (data) {
var str = [];
for (var p in data) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(data[p]));
}
return str.join('&');
},
headers: {
'Authorization': 'Basic ' + window.btoa(Config.WEBSERVICES_AUTH),
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
const {access_token, refresh_token} = response.data;
dispatch({type: constants.LOADING_PAGE, payload: { common: false }})
dispatch({
type: constants.LOGIN_SUCCESS,
payload: {
access_token: access_token,
refresh_token: refresh_token
}
});
saveTokens(response)
browserHistory.push('/questions');
refreshToken(response);
})
.catch(error => {
dispatch({type: constants.LOADING_PAGE, payload: { common: false }})
//401 Error catch
if(error.response.status === 401) {
throw new SubmissionError({username: 'User is not authenticated', _error: message.LOGIN.loginUnAuth})
}
//Submission Error
throw new SubmissionError({username: 'User does not exist', _error: message.LOGIN.loginFailed})
})
}
/**
* Save tokens in local storage and automatically add token within request
* @param params
*/
export function saveTokens(params) {
const {access_token, refresh_token} = params.data;
localStorage.setItem('access_token', access_token);
if (refresh_token) {
localStorage.setItem('refresh_token', refresh_token);
}
//todo fix this later
getinstanceAxios().defaults.headers.common['Authorization'] = `bearer ${access_token}`
}
/**
*
*/
export function getTokens() {
let accessToken = localStorage.getItem('access_token');
return accessToken
}
/**
* update the get requests
*/
export function updateTokenFromStorage() {
const tokenLocalStorage = getTokens();
getinstanceAxios().defaults.headers.common['Authorization'] = `bearer ${tokenLocalStorage}`;
}
/**
* Refresh user access token
*/
export function refreshToken(dispatch) {
//check timestamp
//check access expired - 401
//request new token, pass refresh token
//store both new access and refresh tokens
}
【问题讨论】:
-
为什么不为你的所有请求创建一个拦截器。这个拦截器会检查你的令牌是否仍然有效,你知道吗?如果没有,请发送到新路线或显示一些消息。
-
感谢 Valter - 我将研究 axios 的拦截器。
标签: reactjs axios redux-thunk