Ok so I have a ticket open on this, but I’d also like to see if the community can help.
I have auth0 set up on my angular app. At the moment a user can log in and their user credentials are returned.
However, now I want the user token sent over to a api I have registered with auth0 too.
I followed the guide provided by auth0 here:
I provided the http interceptor as such leaving out scopes (hopefully thats not my problem, because I intend not to use scopes)
imports: [
BrowserModule,
RouterModule,
FontAwesomeModule,
RecaptchaV3Module,
FormsModule,
HttpClientModule,
AppRoutingModule,
AuthModule.forRoot({
domain: environment.auth0_domain,
clientId: environment.auth0_client_id,
redirectUri: window.location.origin,
audience: '<the api identifier i picked>',
// The AuthHttpInterceptor configuration
httpInterceptor: {
allowedList: [
{
uri: 'http://127.0.0.1:8000/api/*',
tokenOptions: {
audience: '<the api identifier I picked>'
}
}
],
},
})
],
providers: [Addemailtomarketinglistservice,
{ provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true },
{provide: RECAPTCHA_V3_SITE_KEY, useValue: environment.recaptcha_site_key },
Googlerecaptchaservice, AuthService, HidecomponentService, S3Service],
bootstrap: [AppComponent]
I am leaving out the server side code because I check my test server, and it gets no request.
Now again, I have already logged the user in, but I am still getting the error:
ERROR Error: Login required
at new n (auth0-spa-js.production.esm.js:15)
at Function.n.fromPayload (auth0-spa-js.production.esm.js:15)
at s (auth0-spa-js.production.esm.js:15)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:27492)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:480)
at invokeTask (zone-evergreen.js:1621)
at globalZoneAwareCallback (zone-evergreen.js:1658)
thinking this could be an issue with my code copied from the auth.service.ts example in this tutorial:
I am dumping my entire auth.service.ts
file.
Its alot to look at, but at this point I am up in arms. I don’t get it. A user is returned. Why am I getting this issue? Thank you very much
import { Injectable } from '@angular/core';
import createAuth0Client from '@auth0/auth0-spa-js';
import Auth0Client from '@auth0/auth0-spa-js/dist/typings/Auth0Client';
import { from, of, Observable, BehaviorSubject, combineLatest, throwError } from 'rxjs';
import { tap, catchError, concatMap, shareReplay } from 'rxjs/operators';
import { Router } from '@angular/router';
import {environment} from '../../environments/environment';
import {HttpClient} from '@angular/common/http';
@Injectable()
export class AuthService {
// Create an observable of Auth0 instance of client
auth0Client$ = (from(
createAuth0Client({
domain: environment.auth0_domain,
client_id: environment.auth0_client_id,
redirect_uri: `${window.location.origin}`,
useRefreshTokens: true,
cacheLocation: 'localstorage'
})
) as Observable<Auth0Client>).pipe(
shareReplay(1), // Every subscription receives the same shared value
catchError(err => throwError(err))
);
// Define observables for SDK methods that return promises by default
// For each Auth0 SDK method, first ensure the client instance is ready
// concatMap: Using the client instance, call SDK method; SDK returns a promise
// from: Convert that resulting promise into an observable
isAuthenticated$ = this.auth0Client$.pipe(
concatMap((client: Auth0Client) => from(client.isAuthenticated())),
tap(res => this.loggedIn = res)
);
handleRedirectCallback$ = this.auth0Client$.pipe(
concatMap((client: Auth0Client) => from(client.handleRedirectCallback()))
);
// Create subject and public observable of user profile data
private userProfileSubject$ = new BehaviorSubject<any>(null);
userProfile$ = this.userProfileSubject$.asObservable();
// Create a local property for login status
loggedIn: boolean = null;
constructor(private router: Router, private http: HttpClient) {
// On initial load, check authentication state with authorization server
// Set up local auth streams if user is already authenticated
this.localAuthSetup();
// Handle redirect from Auth0 login
this.handleAuthCallback();
}
// When calling, options can be passed if desired
// https://auth0.github.io/auth0-spa-js/classes/auth0client.html#getuser
getUser$(options?): Observable<any> {
return this.auth0Client$.pipe(
concatMap((client: Auth0Client) => from(client.getUser(options))),
tap(user => {
this.userProfileSubject$.next(user);
console.log(user);
})
);
}
private localAuthSetup() {
// This should only be called on app initialization
// Set up local authentication streams
const checkAuth$ = this.isAuthenticated$.pipe(
concatMap((loggedIn: boolean) => {
if (loggedIn) {
// If authenticated, get user and set in app
// NOTE: you could pass options here if needed
return this.getUser$();
}
// If not authenticated, return stream that emits 'false'
return of(loggedIn);
})
);
checkAuth$.subscribe();
}
login(redirectPath: string = '/') {
// A desired redirect path can be passed to login method
// (e.g., from a route guard)
// Ensure Auth0 client instance exists
this.auth0Client$.subscribe((client: Auth0Client) => {
// Call method to log in
client.loginWithRedirect({
redirect_uri: `${window.location.origin}`,
appState: { target: redirectPath }
});
});
}
private handleAuthCallback() {
// Call when app reloads after user logs in with Auth0
const params = window.location.search;
if (params.includes('code=') && params.includes('state=')) {
let targetRoute: string; // Path to redirect to after login processsed
const authComplete$ = this.handleRedirectCallback$.pipe(
// Have client, now call method to handle auth callback redirect
tap(cbRes => {
// Get and set target redirect route from callback results
targetRoute = cbRes.appState && cbRes.appState.target ? cbRes.appState.target : '/';
}),
concatMap(() => {
// Redirect callback complete; get user and login status
return combineLatest([
this.getUser$(),
this.isAuthenticated$
]);
})
);
// Subscribe to authentication completion observable
// Response will be an array of user and login status
authComplete$.subscribe(([user, loggedIn]) => {
// Redirect to target route after callback processing
this.router.navigate([targetRoute]);
});
}
}
logout() {
// Ensure Auth0 client instance exists
this.auth0Client$.subscribe((client: Auth0Client) => {
// Call method to log out
client.logout({
client_id: environment.auth0_client_id,
returnTo: `${window.location.origin}`
});
});
}
// for sending the user object from the backend
serversidebehaviorsubject = new BehaviorSubject(null);
sendserversideuser(user){
this.serversidebehaviorsubject.next(user);
}
receiveserversideuser():Observable<any>{
return this.serversidebehaviorsubject.asObservable();
}
}