Please be aware that this is my attempt to get a second opinion on Ryan Chenkie’s answer to the issue I posted a week ago as Lock based authentication setup - Auth0 Community.
Since that time, I did manage to learn a lot more about Lock API and have deployed the application that in my opinion still misbehaves (click here to run it) and check this document for more details on the app structure and behavior.
In summary, click on the “GitHub Users” menu item, results with the Auth0 lock prompt, and if you just click on the provided ID (auth0test@aureliatools.com), you will see the application that is already running, to reload itself.
I saw many statements about this behavior being unavoidable for SPA apps - but I would really like to understand why. Giving me the complete definition of the Auth0 response to the authentication request, so I can simulate Auth0 Lock using Postman tool would be ideal.
Since this is the place that expects precise questions in order to get useful answers, let me add the following:
Initial setup
let options = { rememberLastLogin: true, auth: { redirectUrl: 'http://localhost:9000/#/auth0-service', responseType: 'token', sso: true }, theme: { labeledSubmitButton: true }, allowForgotPassword: true, allowSignUp: false, allowedConnections: 'Username-Password-Authentication'], prefill: { email: "auth0test@aureliatools.com", username: "auth0test" }, hashCleanup: false, autoParseHash: false }; // // Auth0Lock is created here - when the Auth0Service gets added to the DI container // executing 'import { Auth0Service } from './services/auth0-service';' statement in app.js // try { this.lock = new Auth0Lock(client_ID, domain, options); } catch (e) { console.log(e.message); }
My choice of options can be inconsistent for what I want to achieve, so this is clearly an area where I expect to be found at fault.
I am also unsure on how to use the resumeAuth API, so my current implementation of the “authenticated” event handler is:
registerAuth0EventHandler(router, lock) { // Lock event handler - at the moment used only to set the state of being authenticated // and gather user profile / JWT bearer token // this.lock.on("authenticated", (authResult) => { this.lock.getProfile(authResult.idToken, (error, profile) => { if (error) { console.log("getProfile failed.") return; } this.showUserCredentials(authResult, profile); this.isAuthenticated = true; lock.hide(); let returnRoute = localStorage.getItem('returnRoute'); router.navigate(returnRoute); }); }); } showUserCredentials(authResult, profile) { let _profile = JSON.stringify(profile); let _id_token = authResult.idToken; console.log('EventHandler in the Auth0Service module reporting:'); console.log('token: ' + _id_token); console.log('profile: ' + _profile); }
Related to this specific issue, my questions are:
- Does resumeAuth API follow the
lock.on(“authenticated”,
function(authResult) - or it is used
instead? - In my implementation I use
Aurelia’s DI, with the
consequence that the Lock is
instantiated only once (when fetched
from the Dependency Container for
the first time). Based on my reading
of the Auth0 documentation, is seems
that this might be wrong as the Lock
behaves as a singleton (for a
specific client, that is), so I
might be in trouble by optimizing my
code
Update (in reaction to @jmangelo answer)
Your paragraph
In a process like this the (HTTP) redirect happening at the fourth step implies that for a SPA the application will have to reload because the browser is moving from one web application (identity provider) to another (the SPA). Since this is mandated by OAuth2/OIDC you’ll find references to the unavoidable situation in SPA’s which is mostly correct.
is the answer I am looking for more than a month. Not having sufficient Auth0 experience (do not take this as stating that I do not have sufficient identity management experience, though :-)) I was suspicious of everything and wanted one firm anchor to start from. Thank you for providing it now.
Let me also argue your point the application will have to reload because the browser is moving from one web application (identity provider) to another (the SPA)
. My application has a very special relationship with Auth0 - as defined on the Dashboard, so I could envision a solution where the redirect to my app’s Allowed Callback URL
(with proper definition of Allowed Origins
) can perceived by my app as a simple navigation request to a different route, invoking the module where the data returned by Auth0 are processed, without any app reload taking place. This behavior after all is precisely the reason SPA was “invented”, just like AJAX was created to prevent full page refresh.
Now, I am not asking you to implement this behavior - my whole point is to ensure that I am not doing something really silly, while representing Auth0 to the Aurelia Community, where everybody understands HTTP protocol and very few know how to use Auth0. To say it differently, I am constantly seeking for best Auth0 development practices, just like am doing the same on the Aurelia side.
Finally, my original aim is to illustrate the concept of “late authentication” (do it if and when needed) - and at the time there could be a lot of “application” state that I would have to persist across authentication. This in itself is not an unsolvable problem by any means - it would just seem unnecessary if people do not understand your just provided explanation of the "necessary application reload*.
I understand that my idea to “improve” the communications between the Auth0 and my SPA app is not compliant with OAuth2/OIDC, so let’s see if they will enhance the current protocol at some later time.