Issue
When I login to my SPA, it doesn't remove the query parameters code and state from the URL, which is problematic as if we refresh the page, the login flow tries again with the parameters that are in the URL. Example of the URL after logging in : http://localhost:4200/?code=0PGoD336KY3sxCfgU539H5V5tF_odyn_46NasddHsMA&state=UXhQY3B5a1FXQ09LSmx1VkptMmxBQzNfWks1bGkwMFBUejdHaEhzT0dncTBi
I'd like angular-oauth2-oidc to remove those parameters, which should already be the case as I understand with the preventClearHashAfterLogin option (which is already as false).
This issue only appears with chrome, I fixed it in Firefox by doing a location.hash = '';
in the login sequence method, even tho it feels more like a hack than a true fix.
This is the code that does the login, I'm not sure if the error is in here, but I've seen that in the tryLoginCodeFlow
there is something to remove the query parameters.
runInitialLoginSequence(): Promise<void> {
return this.oauthService.loadDiscoveryDocument()
.then(() => {
this.oauthService.setupAutomaticSilentRefresh();
return this.oauthService
.tryLoginCodeFlow()
.then(() => {
if (this.oauthService.hasValidAccessToken()) {
// we are authenticated
this.logger.debug('User is authenticated using stored access token');
this.#isAuthenticatedSubject$.next(true);
location.hash = '';
return Promise.resolve();
}
// code removed as the only case where the error happens is when we refresh - thus when we have an access token in the storage
});
}).catch((e: OAuthErrorEvent | HttpErrorResponse) => {
// error handling
});
}
Solution
According to the documentation, one way to achieve this is to redirect after login with router.navigate(['/'])
But that would redirect to the root page of the application, which is not necessarily the desired behavior.
If you want the user to be redirected to the requested initial URL after login, you can use this snippet :
try {
await this.authService.runInitialLoginSequence();
// Initial login sequence failed, redirect to initial location path
await this.router.navigateByUrl(this.location.path());
} catch (err) {
// Initial login sequence failed, handle oidc error here
}
You also need to import Location
from Angular library or it won't work
import {Location} from '@angular/common';
then inject it in constructor
constructor(
private location: Location,
...
) {
}
Answered By - Stephane Janicaud
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.