auth0 / auth0-angular Goto Github PK
View Code? Open in Web Editor NEWAuth0 SDK for Angular Single Page Applications
License: MIT License
Auth0 SDK for Angular Single Page Applications
License: MIT License
I would like signup tab to be displayed by default on the universal login.Leveraging this api, I do not see options for such a feature.
A parameter to pass to loginWithRedirect similar to other sdks {screen_hint:"signup"}.
None that I know of, but there seems to be support in the auth-spa-js client. I could be missing something here..
Trying to set up in my app.module.ts
:
...
AuthModule.forRoot({
domain: "myDomain.eu.auth0.com",
clientId: "myClientID",
audience: "myAudience"
}),
...
When I decode the returned token I get: "aud": "myClientID"
not "aud": "myAudience"
So basically my token is useless for my api.
auth0-angular
used: 1.3.1I am trying to migrate away from using @auth0/angular-jwt + other old code to auth0-angular. In angular-jwt, I am using the ability to set a deny list as such:
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: [ // domains to allow // ],
blacklistedRoutes: [ // domains to disallow, overriding whiteListedDomains //]
})
However, based on my understanding / reading of current documentation, there is only an option for an allowedList, but none for a corresponding deniedList.
Be able to specify a deniedList inside the httpInterceptor option within
AuthModule.forRoot(
.
Be very explicit in your allowedList instead of wild-carding with
*
.
Currently I can only decide if I always or never want a token to be attached to a request. I'm not aware of a way to have a token attached to a request if the user is authenticated and to send the request without a token if the user is not authenticated.
This is a problem for Endpoints which serve content to authenticated and un-authenticated users.
The ideal solution would be for the interceptor to wait till initial authentication procedure is finished and then continue dispatching requests with a token or without.
My current workaround is a interceptor which calls getAccesssTokenSilently() and adds a token upon success or no token upon error but dispatches the request in both cases. This is not ideal (because I can't just observe the accesstoken), but it works.
Other people seem to have the same usecase as me: https://community.auth0.com/t/auth0-angular-http-interceptor-error-when-user-is-not-logged-in/50866/3
I want my users to be able to update some information about themselves (their user_metadata) via an angular app ( for example: firstname and lastname). Currently I'm not aware of a possibility to do this with auth0-angular.
auth0.js offers patchUserMetadata() to patch the user metadata. It would be grand if auth0-angular could offer a similar function.
My current workaround is to create a separate endpoint on my backend service which accepts the user_metadata and forwards it to auth0
Our account currently has a rule to check if a user is allowed to access a particular application, and if they do not, it throws an unauthorized error. Note that this user may and likely does have access to other applications, just not this particular application.
When unauthorized error is thrown in the rule, the application using the Angular Auth0 library finds the user to be unauthenticated (which is probably fine) but throws the user into an infinite redirect loop. I believe this is caused by this line
We're currently able to prevent this loop by logging the user out in a callback page; however, this is undesirable because the user will need login again to access any of our other applications.
It would be nice if there were some way to provide a url or function of sorts for errors like this where the user is quasi logged in so we could respond to errors accordingly.
I cannot share a sample, but would be happy privately demo the issue or try to provide further details as needed.
Please provide the following:
auth0-angular
used: ^1.2.0For the bug to reprocude, following conditions must be met:
Due to incognito mode auth0 does not send all the cookies, so instead of getting token silently it does the full flow. Afther that is sucessfully obtains an acess token. Saying that, when above conditions are met, auth0 fails to add the token to the requests and tries to authorize again - this time with propmt param set to none (my gues is ib this moment the lib ties to obtain token silently). In console ERROR Error: Uncaught (in promise): Error: Login required error is visible, and requests are not beeing sent.
The second and following authorization endpoint calls should not happen. Requests should be sent with proper token attached.
Hi!
First of all: Thank you guys for building an awesome library! It saved us a lot of work. Hopefully, this bug report helps to make it even more awesome. Here's what I'm running into.
I'm using the auth0-angular library in our Angular 9 spa and I ran into this issue: In our application, we show the name of the logged-in person. We use the id_token to get the name. We have a way the user can change his name, we use the auth0 API to update his claims in Auth0. In the SPA we use the authService.getAccessTokenSilently({ignoreCache: true})
to renew the access_token and the id_token and we expect it to contain the new name. And it does! When I inspect the localstorage, and copy the id_token from it, and inspect it at jwt.io, I can see that the name has been updated in the id_token correctly, as I expected. But the authService.user$
is not being updated, so the spa does not show the new name.
To be brief, this is my test-case:
Scenario: Renewing tokens after the claims have been changed
Given somebody has logged into my SPA
And the access_token and the id_token have been retrieved and are stored in localstorage/sessionstorage
And the claims of the id_token have changed in Auth0 after the access_token and id_token have been retrieved in the SPA
When the tokens are renewed using authService.getAccessTokenSilently({ignoreCache: true})
Then the authService.user$ observable should be showing values of the changed claims!
Steps to reproduce:
Please let me know if this bug report provides enough information to get it fixed. Also, please let me know if it's appreciated if I try to fix it myself and make pull request.
Thanks in advance,
I have code which logins user using Auth0 Universal Login window by calling loginWithPopup().
After successful login, I expect isAuthenticated$ and user$ observables to emit new values, but they don't.
I can try to provide simple amp, if you have existing sandbox template/workflow for this.
I used this great lib to connect with cognito instead of auth0. Everything works great, but the token endpoint has CORS error. This lib is using /oauth/token as the url. It it hardcoded in the code. If I could change that to /token it would have worked (I tested that with other lib).
My organization does not use the angular environment files for build variables because that method forces the application to be rebuilt in every CI/CD environment which introduces instability. Instead, we include an appSettings.json file with our package and let the application query for environment specific variables on load. This means that configuration via the module.forRoot() parameters isn't possible as it replies on a typescript file getting compiled into the app.
Our internal configuration provider package is designed to grab the values out of appSettings and provide them in a service to the app. Ideally Auth0 would give us the option to delay configuration until services are provided like so:
constructor(
public configService: NgAppConfigService,
public auth0: Auth0Service) {
const config = this.configService.getconfig();
this.auth0.initialize(config.auth0Settings);
}
Our current workaround is to use our internal Auth0 wrapper (@sigao/ng-auth0) that allows for initialization via the service. However, we would like to switch over to using the SDK if possible.
For cases where tasks have to be performed post-login and pre-redirect callback. Maybe call an API to update user meta data, or check for additional user rights. I´ve considered Auth0 Auth Pipelines such as hooks and rules, however, some cases cannot be resolved with these concepts, and you might want to have the code reside in your app. See questions/discussions like the one in this issue #53.
It would be nice to be able to "inject code" that is supposed to be performed post-login and return a boolean before redirect callback is carried out. This might be added to any of the following functions in auth.service.ts: (checkSessionOrCallback, handleRedirectCallback, or shouldHandleCallback).
In my browser German is the default language. However, the login dialog provided by Auth0 is always in English.
The login dialog should use the language that is configured in the browser.
auth0-angular
used: 1.0.0Hi, I tried to run my application using server-side rendering (SSR) with Angular Universal but got 'window is not defined' -error.
Problem seems to be in auth.client.ts -file:
return new Auth0Client({
redirect_uri: redirectUri || window.location.origin,
client_id: clientId,
max_age: maxAge,
...rest,
auth0Client: {
name: useragent.name,
version: useragent.version,
},
});
}
No "window is not defined" -error.
auth0-angular
used: 1.2.0Is it possible to make the auth SDK logout call an observable or a promise?
At the moment my app is very reactive and when the user logs out. There is always time delay until the logout call is completed.
It would be good to hook up this async call into a stream and perform actions based on completion or even errors by having either an observable or promise api.
What do you think? :)
I'm using auth0-angular to provide Auth0 login for the admin module of a small Angular-based web application. I've configured auth0-angular to redirect to my admin route after login. The import config in my main app module looks like this:
AuthModule.forRoot({
domain: 'MY-DOMAIN.us.auth0.com',
clientId: 'MY-CLIENTID',
redirectUri: 'http://localhost:4200/admin',
}),
Initially this works as expected. I'm redirected back to http://localhost:4200/admin after login. BUT, after the login is processed, auth0-angular then fires Router.navigate('/') and sends me to the application root.
Is this the expected behavior? Instead, I would like to STAY on the '/admin' route after the session is loaded, instead of automatically navigating back to '/'. Is there a way to configure that behavior?
This should be simple to reproduce by configuring a redirectUri to return the user somewhere other than '/'.
Please provide the following:
auth0-angular
used: 1.0.0Hi !
I have a trouble which I can reproduce with the playground application.
I have two apps : domain1 and domain2 (this last one are your playground application).
There are all configured on the same auth0 domain.
I have to use getAccessTokenSilently() method on domain2 to be authorized to use my API.
When I'm authenticated on domain1 and I want to access to domain2,
I'm first considerate as unauthenticated by the package, which is not good.
But when I refresh the page I'm finally considerate as authenticated.
I should not have to refresh the page of domain2 to be authenticated.
I have maybe a solution, in the service auth.service.ts we have this
const checkSessionOrCallback$ = (isCallback: boolean) =>
iif(
() => isCallback,
this.handleRedirectCallback(),
defer(() => this.auth0Client.checkSession())
);
We could have this, and it's working in my case :
const checkSessionOrCallback$ = (isCallback: boolean) =>
iif(
() => isCallback,
this.handleRedirectCallback(),
defer(() => this.auth0Client.getTokenSilently())
);
But I'm not sure it's a good solution.
Or, when we use the method of this same service getAccessTokenSilently, and if it successful, we could emit true on the Subject isAuthenticatedSubject$, so that we are authenticated now.
What do you think ?
The current playground application, with Chromium and Firefox.
following the documentation on dynamically loading configuration causes error on startup. "Configuration must be specified either through AuthModule.forRoot or through AuthClientConfig.set.
I'm sure there's something I'm just not seeing in the docs, but....
attempting to inject AuthService from @auth0/auth0-angular into an Injectable class causes the bootstrapped to fail
the application to bootstrap and run
export function configInitializer(
http: HttpClient,
config: AuthClientConfig
) {
return () =>
http
.get('assets/config/config.json')
.toPromise()
.then((loadedConfig: AuthConfig) => {
config.set(loadedConfig)
});
}
AuthModule.forRoot(),
{
provide: APP_INITIALIZER,
useFactory: configInitializer,
deps: [HttpClient, AuthClientConfig],
multi: true,
},
ng build && ng serve
auth0-angular
used: 1.3.2It should be possible to have a method to listen if the accesstoken is refresh and get the new accesstoken.
I create a web-worker via Angular CLI and without any configuration the build fail with:
ERROR in ./node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js
Module parse failed: Cannot read property 'length' of undefined
Good way to build
ng g web-worker web-worker
ng build
ERROR in ./node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.esm.js
Module parse failed: Cannot read property 'length' of undefined
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
TypeError: Cannot read property 'length' of undefined
at /home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/worker-plugin/src/index.js:55:46
at SyncBailHook.eval (eval at create (/home/path/to/project/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:5:16)
at Parser.walkNewExpression (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1822:25)
at Parser.walkExpression (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1613:10)
at Parser.walkExpressions (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1569:10)
at Parser.walkSequenceExpression (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1726:36)
at Parser.walkExpression (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1619:10)
at Parser.walkTerminatingStatement (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1081:32)
at Parser.walkReturnStatement (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1085:8)
at Parser.walkStatement (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:985:10)
at Parser.walkStatements (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:868:9)
at /home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1017:9
at Parser.inBlockScope (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:2060:3)
at Parser.walkBlockStatement (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1014:8)
at Parser.walkStatement (/home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:949:10)
at /home/path/to/project/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Parser.js:1702:10
auth0-angular
used: 1.0.0isAuthenticated$ observable of AuthService emits true even when the idToken has expired.
Just to note, user$ observable emits undefined, which is expected.
I have guarded HomeComponent route with AuthGuard available from auth0-angular lib. However even when idToken has expired the canActivate seems to pass (returns true).
import { AuthService } from '@auth0/auth0-angular';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(public auth: AuthService) { }
ngOnInit(): void {
this.auth.user$.subscribe(v => console.log(v));
this.auth.isAuthenticated$.subscribe(v => console.log(v));
}
}
I'm expecting AuthGuard to fail (canActivate return false) and auth.isAuthenticated$ to emit false.
auth0-angular
used: 1.3.1Angular is now at version 11. Installing @auth0/auth0-angular
is only possible with --force
or --legacy-peer-deps
arguments.
We are expecting a clear install without having to force it.
Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent.
Note: If clear, reproducable steps or the smallest sample app demonstrating misbehavior cannot be provided, we may not be able to follow up on this bug report.
npm i @auth0/auth0-angular
➜ ### git:(master) ✗ npm i
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: @###@1.0.0
npm ERR! Found: @angular/[email protected]
npm ERR! node_modules/@angular/common
npm ERR! @angular/common@"~11.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/common@"^10.0.2" from @auth0/[email protected]
npm ERR! node_modules/@auth0/auth0-angular
npm ERR! @auth0/auth0-angular@"^1.2.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
Please provide the following:
auth0-angular
used: ^1.2.0getAccessTokenSilently
ignores auth0Config changes via authClientConfig.set()
.
Consider this small code snippet:
Line 1-3 sets a changed auth0Config via authClientConfig.set()
.
Line 4 requests a new token.
const auth0Config = this.authClientConfig.get();
auth0Config.scope += 'someNewScope';
this.authClientConfig.set(auth0Config);
return this.authService.getAccessTokenSilently()
I would expect getAccessTokenSilenty
to get a new token from auth0 using the changed scopes.
Instead it returns the cached token (no network calls shown in the browser network tab).
I used getAccessTokenSilently({ignoreCache: true})
as a workaround.
Now a new token is requested, but with the old scopes.
Only getAccessTokenSilently({ignoreCache: true, scope: auth0Config.scope})
makes a network call using the correct scopes.
I'm not sure, if the old scopes will be used again once I call getAccessTokenSilently
without any arguments.
auth0-angular
used: 1.3.2Following the quick start guide when I reduce the Token Expiration (Seconds)* to 30, all routes with the AuthGuard still fire.
AuthGuard should redirect to Auth0 universal login page if isAuthenticated is false.
Please provide the following:
auth0-angular
used: 1.2redirectUri
is not working so it is not possible to redirect the user to some other page after login into the app.
User gets redirected after loging in.
The problem is easily reproducible with the sample application, here the issue: auth0-samples/auth0-angular-samples#206
Tested on Chrome and Firefox latest versions.
I keep getting a NullInjectorError
in the browser's console when I import AuthService
into a component. I have tried adding AuthService
as a provider in my app.module.ts
as well as in the component, to no avail. I have imported and initialized AuthModule in app.module.ts
.
No error should be thrown, I have mirrored the setup from https://auth0.com/docs/quickstart/spa/angular?framed=1&sq=1#configure-auth0
ng new
npm install @auth0/auth0-angular
AuthModule.forRoot(...)
in moduleprivate auth: AuthService
to AppComponent
constructorauth0-angular
used:When the access token can no longer be renewed and the authorization server responds with "Login Required", the error$ observable does not appear to emit the error. I'm uncertain how to handle this situation in my application without building my own getAccessTokenSilently function.
To receive an error message in the error$ observable which my application can then respond to.
auth0-angular
used: 1.3.1Please do not report security vulnerabilities here. The Responsible Disclosure Program details the procedure for disclosing security issues.
Thank you in advance for helping us to improve this library! Your attention to detail here is greatly appreciated and will help us respond as quickly as possible. For general support or usage questions, use the Auth0 Community or Auth0 Support. Finally, to avoid duplicates, please search existing Issues before submitting one here.
By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.
Currently, the default HttpInterceptor
always throws an exception when trying to send a request to an uri in the configured allowedList
. I think it would be useful in some cases to be able to configure it so that, for specific endpoints, the interceptor tries to add the Authorization header if possible (i.e. if the user is logged in), but still sends the requests anyway, even if that's not the case.
Entries in the allowedList
could have an aditional field, something like continueOnError
(that defaults to false
) that essentially means "I would like this to have the header, but I need it to be sent in any case.".
You can create a custom interceptor that always tries to add the header, but just leaves things untouched if that's not possible.
An example use case is an /available-features
endpoint, that should return what features should be enabled for a particular user. This should not be inaccessible to requests that are not authorized, but authorization changes the result of requests to this endpoint, as permissions play a role in determining the status of a particular feature for the current user.
In my application, I am using both @auth0/auth0-angular and angular-oauth2-oidc. Auth0 for external clients and oauth2 for internal clients. My problems arrives when I try to inject auth0-angular AuthService in my interceptor. Now, whenever I try to get a callback for internal clients (that should be answered by angular-oauth2-oidc, Auth0 will try to capture it and return to "/".. triggering an authentication loop. If I don't use AuthService and instead use the official interceptor, everything runs fine.
Add more checks to make sure the callback is meant for Auth0. Or add a config so that we can control what happened in case an error happened. Personally, I'd prefer if the callback was not answered by Auth0 if it's not meant for it. Maybe it could check if the origin match the expected URL?
The current workaround is to use the official interceptor and never inject AuthService in an interceptor.
The readme examples for the allowedList configuration give the idea that it's possible to pass a partial path with a wildcard like /api/*
, but in practice this doesn't seem to work. Apparently, the interceptor uses startsWith
with everything prior to the wildcard character to check if the token should be added to the request:
So the examples below don't work in practice at the moment:
allowedList: [
...
// Attach access tokens to any calls that start with '/api/'
'/api/*',
// Match anything starting with /api/accounts, but also specify the audience and scope the attached
// access token must have
{
uri: '/api/accounts/*',
tokenOptions: {
audience: 'http://my-api/',
scope: 'read:accounts',
},
},
Tell us about the behavior you expected to see
I expected the examples to match reality ;-)
It makes sense to be strict enough with the URL matching to avoid sending bearer tokens all over the internet though ;-)
Please do not report security vulnerabilities here. The Responsible Disclosure Program details the procedure for disclosing security issues.
Thank you in advance for helping us to improve this library! Your attention to detail here is greatly appreciated and will help us respond as quickly as possible. For general support or usage questions, use the Auth0 Community or Auth0 Support. Finally, to avoid duplicates, please search existing Issues before submitting one here.
By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.
Currently ng-add only installs the library and we need to add AuthModule.forRoot manually, we can automate that too with ng-ad.
We provide promote so user can provide below values while running ng-add
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
once provided, ng-add will below code
AuthModule.forRoot({
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
}),
A clear and concise description of any alternatives you've considered or any work-arounds that are currently in place.
I am interested in doing this change, let me know, would be happy to open the PR.
When using the HttpInterceptor and the AuthGuard (on the root route ('')) in combination with a dynamic configuration that loads a config.json file, I get the error
Configuration must be specified either through AuthModule.forRoot or through AuthClientConfig.set
My guess here is, that it is sort of an chicken-and-egg problem: In order to load the configuration file which I would then use to call AuthClientConfig.set with - the HttpInterceptor is triggered (since it's an http call), however since no auth0 config was set at that point yet, this results in the error above.
Maybe make it so that the interceptor config can either be set beforehand (before the rest of the config - like domain, clientId, etc...) so that it won't throw an error if no config was set yet when the dynamic configuration is loaded, or make the interceptor only check calls if a config was set, otherwise just do nothing.
I basically just used the examples from https://github.com/auth0/auth0-angular and combined AuthGuard on AppComponent ('' route), registering an HttpInterceptor and using a dynamic configuration to load a config.json file that contains domain, clientId and redirectUri.
Please provide the following:
auth0-angular
used: 1.2.0This request is a follow up to #74. I have a use case that I think may more clearly indicate the need for this functionality. Our .Net Core Web API contains 15 Controllers. 3 of these controllers do not require authorization headers for various reasons. Based on the documentation, my understanding is that I would need to specify each of the 12 Controller that need Authorization as "Allowed".
I think a better option would be to add support for an 'except' indicator:
httpInterceptor: {
allowedList: [
{
// Allow all API Endpoints
uri: 'https://MY_DOMAIN/api/*',
}, {
// Except this pattern
uri: '!https://MY_DOMAIN/api/setup*'
}, {
// And this pattern
uri: '!https://MY_DOMAIN/api/public*'
}
]
}
I understand the intent of an explicit allowed list, but without the flexibility to easily exclude a subset, it forces developers into more error prone scenarios. If my API needs a new Controller, I would need to remember to manage this list, or suffer frustration of troubleshooting why no token is being passed. Is it an issue with you Rule? Your Action? The App/API config? I believe it simply make for a more consumable, forgivable API.
This ! indicator's behavior is inline with other similar implementations like glob patterns.
Currently when there is no or expired token and making multiple API requests in parallel or quick succession there is a call to /token
on auth0 for each request. This is inefficient and calls to /token
are rate limited which could result in unnecessary errors.
The interceptor should request a new token for the first matching API request and subsequent requests should await the new token.
Current workaround is to await a single API request prior to any parallel API requests such that the token is already present and valid for the parallel requests.
AuthHttpInterceptor attaches the auth_token to the Authentication header when making an api call (Bearer [auth_token]).
The auth_token is much shorter than the id_token.
AuthHttpInterceptor attaches the id_token to the Authentication header when making an api call (Bearer [id_token]).
The id_token is much longer than the auth_token.
app.module.ts
providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true } ],
Screenshot of browser network tab
auth0-angular
used: 1.0.0Currently, when updating my Angular project to v12, it will report dependencies resolving issue, due to it depends on old Angular 11.
I have to use --force
to install it.
user.sub
to fetch some permissions for the user from an api.user.sub
is being accessed successfully.// ...
guard: [AuthGuard],
resolve: {
users: UserResolver
},
component: LayoutComponent,
// ...
Should result in the user being logged in if not already, some details being fetched for the user, and then that data should be then available on the route in the layout component.
app.module.ts
file.// route
// ...
path: '',
canActivate: [AuthGuard],
resolve: {
users: UserResolver
},
component: LayoutComponent,
// ...
// user-resolver.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, Router } from '@angular/router';
import { AuthService } from '@auth0/auth0-angular';
import { UserPermissionService } from '@myServices';
import { Observable, of } from 'rxjs';
import { mergeMap, tap } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class UserResolver implements Resolve<User[]> {
private user;
constructor(
private service: UserPermissionService,
private auth: AuthService,
private router: Router,
) {}
public resolve(route: ActivatedRouteSnapshot): Observable<User[]> {
// Old method w/ auth0-spa-js (this worked)
// ---
// const auth0Client$ = (from(
// createAuth0Client({
// domain: this.environment.auth0_domain,
// client_id: this.environment.auth0_clientId,
// redirect_uri: this.environment.callbackUrl,
// response_type: 'token',
// audience: this.environment.auth0_audience,
// cacheLocation: 'localstorage',
// })
// ) as Observable<Auth0Client>).pipe(
// shareReplay(1),
// catchError((err) => throwError(err))
// );
// ---
// return auth0Client$.pipe(
// concatMap((client: Auth0Client) => from(client.getUser()))
// ).pipe(
// mergeMap((user) => {
// return this.userPermission.getUserWithUserId(user.sub).pipe(
// tap((users) => {
// console.log('old', users);
// })
// );
// })
// );
return this.auth.idTokenClaims$.pipe(
mergeMap((res) => {
// Alternatively, return of([]); also does not work here
return this.service.getUser(res.sub).pipe(
tap((users) => {
// This fires and I see the correct data
console.log('new', users);
})
);
})
);
}
}
<p>Layout component works!</p>
, but instead fails and is left with blank screen.console.log('new', users)
Please provide the following:
auth0-angular
used:^1.2.0Calling toPromise
on the user$
observable seems to cause a never ending request to /oauth/token
eventually leading to the browser crashing due to ever increasing memory.
public async getCurrentUser(): Promise<any> {
return await this.auth.user$.toPromise<any>();
}
Return a result after the request has been completed.
See description.
Please provide the following:
auth0-angular
used: 0.2.1 and 1.0.0Please do not report security vulnerabilities here. The Responsible Disclosure Program details the procedure for disclosing security issues.
Thank you in advance for helping us to improve this library! Your attention to detail here is greatly appreciated and will help us respond as quickly as possible. For general support or usage questions, use the Auth0 Community or Auth0 Support. Finally, to avoid duplicates, please search existing Issues before submitting one here.
By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I've just spent a couple days bashing my head against the wall over why my auth0 app worked on PC, Mac, and Android phones, but not in any browser in iOS. The login works correctly, but it was unable to call my APIs, and get a message from error$ saying 'Login Required'. When I read more about how the httpInterceptor worked by silently logging in using cookies, I looked a bit more into cookie management in iOS browsers, and found that it worked when I enabled the "Allow Cross-Website Tracking" in each browser's settings. I don't know too much about what kind of cookies qualify to be blocked by this setting, but it's certainly not ideal to have to tell the audience for my site to enable this setting just to be able to access it.
A clear and concise description of what you want to happen.
I don't have a concise plan of action, but the hope is that I can use the httpInterceptor in my site without enabling the Allow Cross-Website Tracking setting in my iOS browser.
A clear and concise description of any alternatives you've considered or any work-arounds that are currently in place.
The current workaround is to enable this setting.
Add any other context or screenshots about the feature request here.
My identity provider is complaining that the query params I call Authorize with contains the httpInterceptor.
In fact, after looking at the networking tab, it seems I really redirect with httpInterceptor in the params.
[...]&httpInterceptor=%5Bobject%20Object%5D&ui_locales=fr&response_type=code&response_mode=query
If I remove the httpInterceptor from the AuthConfig, it is then not sent in the URL.
httpInterceptor shouldn't be included in the queryParams call to Authorize.
Not use the official HttpInterceptor.
Since right now, I use multiple Auth Providers, I'm cornered because on one side, there's #86 that force me to use the default interceptor and on the other, there's this queryParams that breaks my Auth0 if I don't use a custom interceptor.
Hey all,
I believe this repo previously housed the SDK that supported AngularJs 1.x apps. Though the SDK is still available in npm under the same name ( https://www.npmjs.com/package/auth0-angular ), it has been removed from the bower. Our app which is based on AngularJS 1.5 still uses the old SDK.
Would like to know whether this is intentional and said NPM package will be removed in the future?
I am using the new dynamic configuration to set the various Auth0 Config properties like domain, clientId, and httpInterceptor.
Problem - The httpInterceptor uri/audience options aren't being picked up. As a result, my http.get
API calls do not have an Authorization header on them.
Authorization header should appear on API requests when specified in httpInterceptor
Following the Dynamic Configuration instructions, I didn't pass anything in the .forRoot()
in app.module.ts imports section.
AuthModule.forRoot()
I set up the App Initializer and HTTP Interceptor:
{
provide: APP_INITIALIZER,
useFactory: configInitializer, // <- pass your initializer function here
deps: [AuthClientConfig,HttpClient],
multi: true,
},
{ provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true },
I set the values directly in the configInitializer
function configInitializer(config: AuthClientConfig, http: HttpClient) {
return () => { config.set({
clientId: "myclientid",
domain: "mytenant.eu.auth0.com",
httpInterceptor: { allowedList: [
{
uri: "/api/*",
tokenOptions: {
audience: "my-audience"
}
}
] }
});
}
}
The httpInterceptor
does not seem to get picked up. The library does not pass any audience when requesting a token, and no Authorization header is present on calls to /api/...
.
If I just copy paste that configuration back into .forRoot()
, all behavior returns to normal, and Authorization header is passed in API requests.
CC @stevehobbsdev please can you try this out, does httpInterceptor
work for you?
auth0-angular
used:: 1.1.0Consider only emitting user$ and idTokenClaims$ if they are different. It seems pointless to me to fire them every time getTokenSilently is called, which could happen incredibly often. Unless of course I'm missing something.
I'd like to remove the default behavior of redirection after callback.
Two are the reasons:
1- The application may need an intermediate page due to reset password ( https://auth0.com/docs/rules/redirect-users ), which means that at that time, the user is not logged.
2- I think the callback is enough to redirect the user in the right page. Why introduce another redirection?
I spent a lot of my precious time due to this issue because it wasn't written anywhere in the documentation ( and i think that i'm not the only one ). I didn't understand why it was redirecting the application back to my home page.
In my opinion, the best solution is to leave this feature only if the developer specifies the app.target property. No redirection, if the property is not specified.
I also recommend to write down this feature in the README.
I'm having troubles with dynamic configuration.
According to the log -statements order seems to be correct -> Config should be set.
Configuration should be set correctly.
AppModule
@NgModule({
declarations: [
AppComponent
],
providers: [
EnvironmentStore,
{provide: APP_INITIALIZER, useFactory: auth0Factory, deps: [AuthClientConfig, EnvironmentStore], multi: true}
]
imports: [
AuthModule.forRoot()
],
bootstrap: [AppComponent]
})
export class AppModule {
Factory Method
function auth0Factory(authClientConfig: AuthClientConfig, environmentService: EnvironmentStore): () => Promise<void> {
return () => {
const config: AuthenticationConfig = environmentService.config.authentication;
authClientConfig.set(config.auth0);
console.log('Called Auth0 factory');
console.log('Auth config:' + JSON.stringify(authClientConfig.get()));
return of<void>().toPromise();
};
}
EnvironmentStore
@Injectable({
providedIn: 'root'
})
export class EnvironmentStore {
private readonly _config: GeneralServiceConfig;
constructor(@Inject(SERVICE_CONFIG_TOKEN) config: GeneralServiceConfig) {
this._config = config;
console.log('EnvironmentStore constructor called');
}
public get config(): GeneralServiceConfig {
return this._config;
}
}
Error
If so, provide steps:
Where applicable, please include:
- The smallest possible sample app that reproduces the undesirable behavior
- Log files (redact/remove sensitive information)
- Application settings (redact/remove sensitive information)
- Screenshots
auth0-angular
used: 1.2.0I was adding in another OAuth provider yesterday for my project, Nylas, which I was having redirect back to my app with both query parameters state and code. I noticed Auth0/Angular (which I believe uses this plugin) was attempting to use the state and code parameters on routes I wasn't intending for them to be consumed, threw an exception, then redirected back to the front page of the app.
I'd like to be able to specify the routes that should be matched when attempting to log in. Since when using Auth0 you're limited to pre-defined redirect paths anyways, it seems like it should be ok to limit the paths at which auth0-spa attempts to detect and digest state and code query parameters in the url.
For example:
Limit the path to: /login/authorize
Or specify which routes to not hit: /app/settings/nylas
Since the two functions in AuthService are private it looks like I can't just extend AuthService and override the functionality.
A solution would be to updating AuthConfig's advancedOptions param to allow specifying an additional function that is checked before or after the current code in shouldHandleFunction() is checked using logical and.
I do like having the option for a simple string config in authModule though, so ideal would be to specify the window route as a string to match on, or simply providing true to only match on the redirectUri string if it is provided.
Right now I updated it so auth redirects from Nylas first go to the api server, which redirects back to the client with different query parameters. I'd rather not do this because it should go straight back to the app itself.
Reposting this over from auth0/auth0-spa-js#646
I have a "User Service" that in turn uses AuthService in order to fetch the user's profile and generate login / logout buttons.
Local run and production build of my Angular 11 App work just fine but ng test is failing with:
NullInjectorError: No provider for InjectionToken auth0.client!
The test should pass.
Adding AuthService as a provider in the .spec.ts file does nothing.
Angular 11
"@auth0/auth0-angular": "^1.4.0",
I would like to have a configuration option where calling loginWithRedirect
in AuthService
will preserve the query parameters in the current URL instead of just calling redirectUri
(which is defaulted to the root).
Currently I do the following which works well, but it took me a while to figure out this is what I needed to do to correctly preserve them:
this.base.loginWithRedirect({
appState: {
target: window.location.search
}
});
The auth configuration object that gets configured from forRoot()
has a preserveInitialQueryString
boolean option, maybe even defaulted to true. If true then as the very last step, the original query parameters before the loginWithRedirect()
call are appended to whatever the target was (usually defaulting to /
).
Currently have to manually include the target: window.location.search
in my state. Thinking this could be implemented by modifying the options before forwarding to the auth0Client
Or instead of implementing this as a feature I think a documentation example or a FAQ would be worthwhile.
Thanks!
Got Auth0 in the compiled capacitor App running like this: https://auth0.com/docs/libraries/auth0-single-page-app-sdk
But it does not work with the angular services: https://auth0.com/docs/quickstart/spa/angular/01-login
I could not find out why. It just does not set the cookie, which is set in the handleRedirectCallback function of the auth-0-spa-client.
And another thing:
My redirect url is app://myapp.com, while my app is running in the capacitor webview on https://myapp.com. With the auth 0 angular service, I get the error, that it is not allowed to be on another URL when calling handleRedirectCallback than the redirect URL was.
I would like to use cypress (cspress.io) to authenticate against auth0-angular.
This blogpost exists which describes how to use cypress to authenticate against auth0 https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/#Cypress. But the post is not using auth0-angular. We recently migrated over from auth0-spa-js to auth0-angular but now we need a way for our integration tests to login into the app. Can you provide information on how to adapt the code in the blog post for it to work again?
It seems the callback URL is diffrent then before (using a code
payload instead of the token itself).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.