I have an app that sometimes need to be embedded in a iframe. Auth0 authentication is set using Google sign in.
In order to prevent CORS issue, I need to make the account selection window appear in a popup.
After a quick search, I found that popup mode seems to be what I’m looking for.
So I edited the default Auth0 Lock code to add redirect: false option. Unfortunately this doesn’t seem to do anything. No window popup is opened, the page still redirects to Google account selection page as before.
Hello @pierre.deville! What technology are you using? The setup for using popup may differ a bit depending on which SDK you’re taking advantage of. Can you give us a little more information on your stack?
Modifying the code inside the universal login page will not affect the context in which that code will run. Since it’s the browser that needs to open the page in a popup window, you’ll want to look at your application in order to trigger that behavior.
You’ll need a way to open the popup from the browser using JavaScript, and then have a callback page that closes the popup again after authentication (this will be your redirect; this is needed so that the popup doesn’t redirect inside its own window and stay open).
This gist is quite old so I would not recommend copy-pasting its contents directly, but the concepts should be consistent: OmniAuth login in popup · GitHub
To log in, open a popup window with JavaScript to your Auth0 universal login page
Upon authentication, your callback redirect should point to a page that closes the popup
I’m not a Ruby expert by any means, but from my understanding, this behavior isn’t built into the omniauth library so you will need to implement it yourself at the application-level.
It is also worth noting that several browsers block programmatically-opened popups by default. If you go with a popup approach, it may be useful to note that you may want to have the popup triggered by a user interaction (like a button click), otherwise it will be blocked in Chrome and Firefox (and potentially other browsers also). Sometimes users miss the “A popup has been blocked” notice in the browser, and they perceive the login as being broken.
Just something to keep in mind when considering your user experience.
Hello @pierre.deville, we are taking a closer look at your initial message and its context, and there are a few challenges you may encounter in this scenario, especially if you are running the application in an embedded iframe. Communicating the authentication results from the popup window back into the calling window (which may be in an iframe) is one such challenge.
Do you have a requirement to use popup over redirect?
Thank you for your answers @kim.maida. I appreciate it.
I do understand this approach and that’s something I can consider, but I thought Auth0 Lock could fire a popup window opening upon clicking on “Log in with Google” button (I found a gif on Lock V10 documentation that shows exactly this, but unfortunately I can’t find it anymore). Could this behavior be happening if the Lock page was self hosted ?
No, actually the only requirement I have is to enable login when this Rails app is embedded in an iframe.
I’d rather use redirect, but for an app in an iframe I get the following browser errors after clicking on “Log in with Google” button (and reaching the Google account selection page)
Refused to display ‘Sign in - Google Accounts’ in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.
I thought handling authentication in a popup could be a nice walkaround, since I have done this in the past for another app but which wasn’t using Auth0 (it was a home made Google Sign In).
Lock (actually Auth0.js, which Lock uses) has provisions for a popup mode, but it’s meant only for SPAs. (We could take this a step further and say that Lock/Auth0.js embedded are only meant for SPAs, not for regular web apps with a back end, which should simply redirect to the /authorize endpoint). What Auth0.js does in popup mode is:
Sets up a web messaging handler to wait for messages from the popup window
Open the popup, navigates to the /authorize endpoint, but with a proprietary value indicating that the response should come as an html page with javascript code that communicates the results to the parent window (this is similar to the now-standard web_message response mode, but predates that standard).
When the parent window receives the response it closes the popup, validates the response, and calls whatever callback was provided in the single page application (so that the callback receives the token results).
Yes, preventing IFRAME embedding of login pages is a standard practice, so these errors are expected.
Like Kim said, it might be possible to do it, but you will have to do all the heavy lifting.
I’m thinking of something like this (keeping in mind that the devil is in the details and I could easily be missing something):
From your app (in the IFRAME) start a web message handler to await results from the popup (making sure communication is only within the same domain). Then open the popup window pointing to /authorize, with a callback URL that is aware of the popup mechanism (see next).
From the handler, process the authentication results, create a session for the web app in the usual way (cookie) and return some HTML that, using web messaging, tells the parent window that “the login from the popup is done, the session was created”.
The parent window, upon receiving this message, should close the popup and force a refresh to pick up the changes now that there’s a session in place (i.e. the user is authenticated).
Another option, if you have control over the parent app that hosts the IFRAME, would be to authenticate the user before loading the IFRAME.