Hello! I am having trouble with properly integrating Auth0 into my Angular application.
I followed this tutorial to integrate Auth0 into my Angular application, the one from the Auth0 docs. I made sure that I followed all of the instructions correctly.
Signing up for an account works, but after signing up, I cannot log in. When executing loginWithRedirect()
after creating an account, it does not launch the login window. It instead takes me back to my app with isAuthenticated$
set to false
. When I look at the client authentication history, I see this:
It says that I had a successful login, but the Identity Provider is N/A. Furthermore, when I look at the success details, Connection is also N/A and “connection_id” is blank. I do not know if this has anything to do with my problem.
I have looked through the Auth0 docs and searched on Google for answers as to why isAuthenticated$
always returns false
after calling loginWithRedirect()
. I have noticed that many people have encountered and solved this problem with many different solutions, but none of those solutions fix my problem.
It is worth noting, however, that if I execute loginWithPopup()
with specific checks that I found online beforehand, it authenticates fine with isAuthenticated$
set to true
. I provided my code at the end of this post with how loginWithPopup()
successfully works for my app.
I do not understand why loginWithRedirect()
always returns isAuthenticated$
as false
no matter what solutions I find online. I have provided my code below.
I am currently using version 2.0.1 of auth0/auth0-angular.
environment.ts
(I have MY_DOMAIN
, MY_CLIENTID
and MY_AUDIENCE
filled in correctly in my app)
export const environment = {
production: false,
auth0: {
domain: 'MY_DOMAIN',
clientId: 'MY_CLIENTID',
redirect_uri: window.location.origin,
audience: 'MY_AUDIENCE'
}
};
app.module.ts
import { AuthModule } from '@auth0/auth0-angular';
import { environment as env } from '../environments/environment';
// ...
@NgModule({
// ...
AuthModule.forRoot({
domain: env.auth0.domain,
clientId: env.auth0.clientId,
authorizationParams: {
redirect_uri: env.auth0.redirect_uri,
audience: env.auth0.audience
},
cacheLocation: 'localstorage'
}),
// ...
})
login.component.html
<div class="container login-container">
<div class="row">
<h1 align="center">
TITLE
</h1>
</div>
<div class="row justify-content-center">
<button mat-flat-button
class="login-button"
type="button"
(click)="attemptLogin()">
Login or Sign Up (Auth0)
</button>
</div>
<div class="row justify-content-center">
<button mat-flat-button
class="login-button"
type="button"
(click)="logout()">
Logout
</button>
</div>
</div>
login.component.ts
(note that logout()
works)
import { Component, OnInit, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService, User } from '@auth0/auth0-angular';
import { OnlineStatusService, OnlineStatusType } from 'ngx-online-status';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
constructor(
public auth: AuthService,
private router: Router,
private onlineStatusService: OnlineStatusService,
@Inject(DOCUMENT) public document: Document
) {
}
ngOnInit(): void {
this.auth.user$.subscribe((value: User | null | undefined) => {
console.log("User:", value);
});
this.auth.isAuthenticated$.subscribe((value: boolean) => {
console.log("Authd:", value);
});
}
// attempt to login with the entered credentials
// solution from https://community.auth0.com/t/isauthenticated-is-always-false/84794/3
attemptLogin(): void {
this.auth.isAuthenticated$.subscribe((value: boolean) => {
if (!value) {
let query: string = window.location.search;
let shouldParseResult: boolean = query.includes("code=") && query.includes("state=");
if (shouldParseResult) {
try {
this.auth.handleRedirectCallback().subscribe((value) => {
console.log("Logged in!", value);
});
} catch (err: unknown) {
console.log("Error parsing redirect:", err);
}
window.history.replaceState({}, this.document.title, "/");
}
else {
this.auth.loginWithRedirect().subscribe((value: void) => {
console.log("Logging in...", value);
});
}
}
else {
this.router.navigate(['home']);
}
});
}
// log out of account and go back to login screen
logout(): void {
if (this.onlineStatusService.getStatus() === OnlineStatusType.OFFLINE) {
this.router.navigate(['login']);
return;
}
this.auth.logout({
logoutParams: {
returnTo: this.document.location.origin
}
});
}
}
01/24/2023 update: I think I know what is happening. When a user is unauthenticated in both my app and on Auth0, loginWithRedirect()
works. After logging in, Auth0 says that I am authenticated, taking me back to my app. However, for some reason, in my app, it says that I am not authenticated. This then causes loginWithRedirect()
to execute again. However, Auth0 says that I am already authenticated, taking me back to my app. This causes an infinite loop where my app says that I am unauthenticated, launching loginWithRedirect()
, while Auth0 says that I am authenticated, taking me back to my app.
Essentially, for some reason, loginWithRedirect()
causes my app to never recognize a user as authenticated, while the Auth0 API does when logging in. Note that this does not happen with AuthGuard
. With AuthGuard
, authentication recognition works perfectly in my app.
01/25/2023 update: Getting loginWithRedirect()
to work may be necessary at this point for building my app. I need my app to detect if a user is online or not, which it currently can. If a user is online, they should authenticate regularly by connecting to Auth0. If a user is offline, they should authenticate through the last retrieved access token while they were online. I do not know if I can do that with canActivate: [AuthGuard]
on each screen.
01/26/2023 update: loginWithPopup()
now works with this solution. Abandoned the AuthGuard
solution. Unfortunately, loginWithRedirect()
still does not work with any of the solutions that I have found.