I a have stack Angular 13 with angular-oauth2-oidc: 13.0.1 and angular-oauth2-oidc-jwks: 13.0.1 for OAuth2.
I'm trying to just redirect the user to the current route before redirecting the login URI.
So currently I'm in implicitflow and I want save the route before the authentication so that after the token received I redirect it to the initial call url.
And my current problem and that can't save the right URL before authentication
@Injectable({
providedIn: "root",
})
export class InitialAuthService {
private jwtHelper: JwtHelperService = new JwtHelperService();
private isAuthenticatedSubject = new BehaviorSubject<boolean>(false);
private isAuthenticated = this.isAuthenticatedSubject.asObservable();
// tslint:disable-next-line:variable-name
private _decodedAccessToken: any;
// tslint:disable-next-line:variable-name
private _decodedIDToken: any;
get decodedAccessToken() {
return this._decodedAccessToken;
}
get decodedIDToken() {
return this._decodedIDToken;
}
get profile() {
return this.oauthService.loadUserProfile();
}
constructor(
private oauthService: OAuthService,
private authConfig: AuthConfig,
public router: Router,
public activeRoute: ActivatedRoute,
private authService: AuthService,
) {
}
async initAuth(): Promise<any> {
const currenturl = this.activeRoute.snapshot.url;
return new Promise<void>((resolveFn, rejectFn) => {
this.oauthService.configure(this.authConfig);
this.oauthService.setStorage(localStorage);
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
// subscribe to token events
this.oauthService.events
.pipe(filter((e: OAuthEvent) => e.type === "token_received"))
.subscribe(({ type }) => {
console.debug("token_received");
this.handleNewToken();
console.debug("before");
console.debug(currenturl);
this.router.navigate([currenturl]);
console.debug("after");
});
this.oauthService.events
.pipe(filter((e: any) => e.type === "token_expires"))
.subscribe(({ type }) => {
console.debug("token_expires");
this.logoutSession();
});
this.oauthService.events
.pipe(filter((e: any) => e.type === "token_error"))
.subscribe(({ type }) => {
console.debug("token_error");
this.logoutSession();
});
this.oauthService.events
.subscribe(_ => {
this.isAuthenticatedSubject.next(this.oauthService.hasValidAccessToken());
});
this.oauthService.loadDiscoveryDocumentAndLogin().then(
(isLoggedIn) => {
if (isLoggedIn) {
resolveFn();
} else {
console.debug("initImplicitFlow");
this.oauthService.initImplicitFlow();
rejectFn();
}
},
(error: { status: number; }) => {
console.log({ error });
if (error.status === 400) {
location.reload();
}
}
);
});
});
}
private handleNewToken() {
this._decodedAccessToken = this.jwtHelper.decodeToken(
this.oauthService.getAccessToken()
);
this._decodedIDToken = this.jwtHelper.decodeToken(
this.oauthService.getIdToken()
);
this.authService.login();
}
logoutSession() {
console.debug("logout");
this.oauthService.logOut();
this.authService.logout();
}
isLogin(): Observable<boolean> {
return this.isAuthenticated;
}
}
Good news: there's built in support on the OpenID protocol for this, and the library supports it. You can clone my sample repository, or more specifically check the two moving parts:
state
parameter of OpenID);Here's the gist of both parts in code:
Again, the sample repository you can clone and just fire up to see all this in action.