I am building a basic auth system with JWT. The following is the basic workflow:
Before I send a request to the API, I have an HttpInterceptor that checks whether or not the token has expired. If it hasn't expired, the interceptor will attach an authorization header to the request with the JWT. If it has expired, the token needs to be refreshed before sending the actual request. When the refresh requests arrives at the backend, it will check the refresh token against the database and remove the entry such that it can only be used once, then it will return a new JWT + refresh token.
Some of my pages fire multiple requests when accessing them and here comes the issue. Multiple referesh requests will be sent at once and hence only the first one arriving at the backend will return succesfully. All other request will return 401 errors which causes issues clientside.
Therefore, I am searching for a way to halt all requests until the first refresh request has returned. The HttpInterceptor calls a function that returns the JWT by checking the expiration date and firing a refresh request if it expired.
Token Interceptor:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Get access token
this._auth.getAccessToken().subscribe((accessToken: string) => {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
return next.handle(request);
});
}
Get Access Token Function:
public getAccessToken(): Observable<string> {
if (!this._authUser) return throwError("User is not logged in."); // Make sure user is logged in
// Refresh token
if (this.checkTokenExpired())
return this.refreshToken().pipe(map(() => this._authUser.tokenManager.accessToken));
return of(this._authUser.tokenManager.accessToken);
}
For simulatenous requests this architecture becomes an issue because the refresh request will be sent multiple times. I need something like a mutex to halt all requests besides the first one and release all of them once the token has been refreshed and return the new JWT.