使用Reactjs,redux,axios和redux-thunk构建登录表单。我有两个令牌 - 一个名为access token
和refresh token
。
对用户进行身份验证后,请存储应持续12小时的access token
。 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
}
答案 0 :(得分:0)
检查一下:
https://github.com/mzabriskie/axios#interceptors
我认为这可以帮到你。您拦截了您的请求并进行了验证。
修改
以下是我试图在我的商店中使用的代码来测试,而不是获取任何记录
import { createStore, applyMiddleware, compose } from 'redux'
import { devTools, persistState } from 'redux-devtools'
import axios from 'axios'
import Middleware from '../middleware'
import Reducer from '../reducers/reducer'
import DevTools from '../containers/DevTools'
let finalCreateStore
if (__DEVELOPMENT__ && __DEVTOOLS__) {
finalCreateStore = compose(
applyMiddleware.apply(this, Middleware),
// Provides support for DevTools:
DevTools.instrument(),
// Optional. Lets you write ?debug_session=<key> in address bar to persist debug sessions
persistState(getDebugSessionKey())
)(createStore)
} else {
finalCreateStore = compose(
applyMiddleware.apply(this, Middleware)
)(createStore)
}
function getDebugSessionKey() {
// You can write custom logic here!
// By default we try to read the key from ?debug_session=<key> in the address bar
const matches = window.location.href.match(/[?&]debug_session=([^&]+)\b/)
return (matches && matches.length > 0)? matches[1] : null
}
axios.interceptors.response.use((err) => {
if (err.status === 401) {
console.log('ACCESS TOKEN EXPIRED!');
}
});
export const store = finalCreateStore(Reducer)