Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interceptors fail to assign new token on second failure #197

Closed
DovahBrownies opened this issue Jul 20, 2022 · 2 comments
Closed

Interceptors fail to assign new token on second failure #197

DovahBrownies opened this issue Jul 20, 2022 · 2 comments

Comments

@DovahBrownies
Copy link

DovahBrownies commented Jul 20, 2022

I'm fairly certain my issue is somewhat related to #123.

Here is the scenario:

The first time the API request(s) fail, the auth refresh logic triggers and the newly generated token is sent with the repeated API request(s).
The second time the API request(s) fail, the auth refresh logic triggers and a new token is generated but the repeated API request(s) are still using the old token.

Network activity:

Network activity (Some explanation):

Code:

const service = axios.create();

const refreshAuthLogic = async failedRequest => {
    const accessToken = await this.refreshToken();
    const formattedAccessToken = 'Bearer' + accessToken;

    failedRequest.response.config.headers['Authorization'] = formattedAccessToken;

    service.interceptors.request.use(request => {
        request.headers['Authorization'] = formattedAccessToken;
        return request;
    });

    return Promise.resolve();
};

const refreshAuthOptions = {
    statusCodes: [401, 403]
};

createAuthRefreshInterceptor(service, refreshAuthLogic, refreshAuthOptions);

Any ideas on how I can consistently assign the new access token to the auth header?

@Flyrell
Copy link
Owner

Flyrell commented Jul 24, 2022

you should set up the assigning interceptor before refreshAuthLogic. Otherwise you're now just adding the interceptors to axios with each fail. So the assigning logic probably runs X-times instead of once.

const service = axios.create();

async function getAccessToken() {
    const accessToken = await this.refreshToken();
    const formattedAccessToken = 'Bearer' + accessToken;

    return formattedAccessToken;
}

service.interceptors.request.use(async request => {
    request.headers['Authorization'] = await getAccessToken();
    return request;
});

const refreshAuthLogic = async failedRequest => {
    // Here you just refresh your token

    // You alter only the failed request
    failedRequest.response.config.headers['Authorization'] = formattedAccessToken;

    // Other requests are altered by the interceptor (as they've not been sent yet)

    return Promise.resolve();
};

const refreshAuthOptions = {
    statusCodes: [401, 403]
};

createAuthRefreshInterceptor(service, refreshAuthLogic, refreshAuthOptions);

@Flyrell Flyrell closed this as completed Jul 24, 2022
@DovahBrownies
Copy link
Author

DovahBrownies commented Jul 26, 2022

Thanks a bunch!
Moving the interceptor out of the function has fixed the problem. But await-ing the getAccessToken() function is potentially problematic. So for anyone stumbling across this issue, I did something very similar:

service.interceptors.request.use(
  request => {
      // If there is a new access token, assign it to the headers.
      // Can be deduced by comparing the existing access token to whatever you save in the localStorage / cookie / global variables / etc...
      if (hasNewAccessToken) {
         request.headers['Authorization'] = newAccessToken;
      }
      return request;
  },
  error => Promise.reject(error)
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants