过期后使用刷新令牌获取访问令牌(JWT)

Getting access token with the refresh token after expiration(JWT)

我在重新加载页面一段时间后收到 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))
}

传奇 users.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,
    },
  })
}

您可以使用拦截器通过刷新令牌获取新的访问令牌。拦截并检查响应状态代码 401,并使用刷新令牌获取新的访问令牌并将新的访问令牌添加到 header.

示例:

return apiClient
  .post(actionUrl, { auth: 'basic' })
  .then(async response => {
    if (response) { // check for the status code 401 and make call with refresh token to get new access token and set in the auth header
      const { access_token: accessToken } = response.data
        store.set('accessToken', accessToken)
      return response.data
    }
    return false
  });

简单的拦截器示例,

axios.interceptors.request.use(req => {
  req.headers.authorization = 'token';
  return req;
});

401 的拦截器示例

axios.interceptors.response.use(response => response, error => {

    if (error.response.status === 401) {
       // Fetch new access token with your refresh token
       // set the auth header with the new access token fetched
    }
 });

有几篇关于使用刷新令牌获取新访问令牌的拦截器的好帖子

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://whosebug.com/a/52737325/8370370