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

[Question]: logoffAndRevokeTokens when multiple requests return 401 #1905

Open
scurk1415 opened this issue Feb 22, 2024 · 0 comments
Open

[Question]: logoffAndRevokeTokens when multiple requests return 401 #1905

scurk1415 opened this issue Feb 22, 2024 · 0 comments
Labels

Comments

@scurk1415
Copy link

scurk1415 commented Feb 22, 2024

What Version of the library are you using?
17.0.0

Question
Is there an elegant way to sign out the user when multiple requests return 401?

Explanation:
I created an ErrorInterceptor which returns the this.oidcSecurityService.logoffAndRevokeTokens() method if the responce status is 401. This works ok if there is only one request fired from the app (only one 401 response in network tab), but if there are more request that fail with 401 (imagine multiple dropdowns getting data from the BE, for example) then my Authority Provider (Keycloak) gives me a message Missing parameter: id_token_hint (not really sure if this is a Keycloak issue or an issue with this library).

My interceptor:

export const errorInterceptor: HttpInterceptorFn = (req, next) => {
  
  const authService = inject(AuthService);
  
  return next(req)
    .pipe(
      catchError((error: unknown) => {
        
        if (error instanceof HttpErrorResponse) {
          if (error.status === 401) {
            return authService.logout();
          }
        }
        
        return throwError(() => error);
      })
    );
};

My service

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private oidcSecurityService: OidcSecurityService = inject(OidcSecurityService);

  logout() {
    return this.oidcSecurityService.logoffAndRevokeTokens();
  }

}

If on the other hand i change my interceptor and service to:

if (error instanceof HttpErrorResponse) {
  if (error.status === 401) {
    authService.logout();
    return NEVER;
  }
}
@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private oidcSecurityService: OidcSecurityService = inject(OidcSecurityService);
  private logoutSubject = new Subject<void>();

  constructor() {
    this.logoutSubject.pipe(
      exhaustMap(() => this.oidcSecurityService.logoffAndRevokeTokens())
    )
      .subscribe();
  }

  logout() {
    this.logoutSubject.next();
  }

}

Then it works correctly and triggers just one request to the revoke endpoint /realms/<realm_name>/protocol/openid-connect/revoke (the erroneous case above triggers multiple revoke calls).

Is there a more elegant way to solve this issue?

PS: this case happens if i Sign Out a session in the Keycloak admin panel (and most likely when the total session time expires too)

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

No branches or pull requests

1 participant