过了一会儿,当页面被重新加载时,我收到401错误,我想这可能是因为访问令牌过期了。我如何用我的刷新令牌设置一个新的令牌?下面的函数在每次用户访问一个新页面或刷新页面时运行。但它似乎不起作用。
export async function currentAccount() {
if (store.get('refreshToken')) {
const query = {
grant_type: 'refresh_token',
companyId: store.get('lastCompanyId'),
refresh_token: store.get('refreshToken'),
}
const queryString = new URLSearchParams(query).toString()
const actionUrl = `${REACT_APP_SERVER_URL}/login?${queryString}`
return apiClient
.post(actionUrl, { auth: 'basic' })
.then(async response => {
if (response) {
const { access_token: accessToken } = response.data
store.set('accessToken', accessToken)
return response.data
}
return false
})
.catch(err => {
console.log('error', err)
store.clearAll()
})
}
return false
}
登录设置访问令牌
export async function login(email, password) {
const query = {
grant_type: 'password',
username: email,
password,
}
const queryString = new URLSearchParams(query).toString()
const actionUrl = `${REACT_APP_SERVER_URL}/login?${queryString}`
return apiClient
.post(actionUrl, { auth: 'basic' })
.then(async response => {
if (response) {
const {
data: {
access_token: accessToken,
refresh_token: refreshToken,
},
} = response
const decoded = jsonwebtoken.decode(accessToken)
response.data.authUser = decoded.authUser
const { userId, profileId, companyId } = decoded.authUser
if (accessToken) {
store.set('accessToken', accessToken)
store.set('refreshToken', refreshToken)
}
return response.data
}
return false
})
.catch(err => console.log(err))
}
** Saga 用户.js**
export function* LOAD_CURRENT_ACCOUNT() {
yield put({
type: 'user/SET_STATE',
payload: {
loading: true,
},
})
const { authProvider } = yield select((state) => state.settings)
const response = yield call(mapAuthProviders[authProvider].currentAccount)
if (response) {
const decoded = jsonwebtoken.decode(response.access_token)
response.authUser = decoded.authUser
yield store.set('id', id)
try {
const user = yield call(LoadUserProfile)
if (user) {
const { company } = user
yield put({
type: 'user/SET_STATE',
payload: {
...user,
preferredDateFormat: user.preferredDateFormat || 'DD/MM/YYYY',
userId,
id,
},
})
}
} catch (error) {
}
}else{
store.set('refreshToken', response.refreshToken)
}
yield put({
type: 'user/SET_STATE',
payload: {
loading: false,
},
})
}
2条答案
按热度按时间66bbxpm51#
你可以使用拦截器用你的刷新令牌获取一个新的访问令牌,拦截并检查响应状态码401,用你的刷新令牌获取一个新的访问令牌,并将新的访问令牌添加到头中。
示例:
简单的拦截器例子
401拦截器示例
有几篇关于使用Interceptors通过刷新令牌获取新的访问令牌的好文章
https://thedutchlab.com/blog/using-axios-interceptors-for-refreshing-your-api-token
https://medium.com/swlh/handling-access-and-refresh-tokens-using-axios-interceptors-3970b601a5da
Automating access token refreshing via interceptors in axios
https://stackoverflow.com/a/52737325/8370370
ny6fqffe2#
上面的答案是好的。但是我发现下面的方法比使用Axios拦截器和"jwt-decode"更好。试试吧。(我在这个例子中使用了会话存储。你可以用你自己的方法安全地存储令牌)
1.登录以获取访问令牌和长期刷新令牌,然后安全地存储它们。
1.创建一个axios示例,用"jwt-decode"检查访问令牌的过期时间,如果存在有效的访问令牌,则将访问令牌添加到请求中,否则使用存储的刷新令牌请求新的访问令牌,然后将新的访问令牌应用到请求中。
登录:
创建axios示例:
在所有请求中使用axios示例(Redux Toolkit示例):