Log in in a popup window

Hello,

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.

Am I missing something ?

Thank you for your answers :slight_smile:

Bump. Anyone to help me please ?

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?

Hello @kim.maida !

Sure, I’m using this ruby gem on a Ruby on Rails application. Nothing fancy has been done to integrate this, I just followed the guides.

The login page is the hosted version Auth0 Lock for web v11 that I just customized to add the redirect: false option.

Here’s how Lock instantiation looks like :

var lock = new Auth0Lock(config.clientID, config.auth0Domain, {
  auth: {
    redirectUrl: config.callbackURL,
    responseType: (config.internalOptions || {}).response_type ||
      (config.callbackOnLocationHash ? 'token' : 'code'),
    params: config.internalOptions,
    redirect: false
  },
  /* additional configuration needed for custom domains
  configurationBaseUrl: config.clientConfigurationBaseUrl,
  overrides: {
    __tenant: config.auth0Tenant,
    __token_issuer: 'YOUR_CUSTOM_DOMAIN'
  }, */
  assetsUrl:  config.assetsUrl,
  allowedConnections: connection ? [connection] : null,
  rememberLastLogin: !prompt,
  language: language,
  languageDictionary: languageDictionary,
  theme: {
    //logo:            'YOUR LOGO HERE',
    primaryColor:    colors.primary ? colors.primary : 'green'
  },
  prefill: loginHint ? { email: loginHint, username: loginHint } : null,
  closable: false,
  defaultADUsernameFromEmailPrefix: false,
  // uncomment if you want small buttons for social providers
  // socialButtonStyle: 'small'
});

Hope this helps, please let me know if you need anything else.

Thanks for your help.

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

  1. To log in, open a popup window with JavaScript to your Auth0 universal login page
  2. 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)

  • Firefox :

Load denied by X-Frame-Options: Sign in - Google Accounts does not permit cross-origin framing.`

  • Chrome :

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):

  1. 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).
  2. 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”.
  3. 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.

Hope this helps.

1 Like

Thank you for your clear and detailed answers.

I’ll try this in the next few days, and let you know how it goes.

1 Like

Hello,

I’m back with some good news.

I did manage to handle authentication to an app embedded in an iframe.

Here’s what I did for those who have the same need I had :

On your app :

Redirect unauthenticated users to a custom login page and not the Auth0 one anymore.

On this page you need to have a link that redirects to the Auth0 lock page. In my case /auth/auth0

<a class="auth-popup" href="/auth/auth0">Login</a>

Then add this piece of JavaScript do handle the click on the link, to open up a pop up

$('.auth-popup').on('click', function(e) {
  window.open($(this).attr('href'), 'authPopup', "menubar=no,toolbar=no");
});

For additional options on popup window size and coordinates, see here : Window.open() - Référence Web API | MDN

Finally, on your callback URL, you need to close the popup and redirect the parent window back to original URL.

Here is the code I used for this

if (!window.opener) {
  window.location = '<%= @redirect_url %>'
} else {
  window.opener.location = '<%= @redirect_url %>'
  window.close()
}

<%= @redirect_url %> is an ERB template tag that return the URL the user comes from. Adapt this to your application and templating language.

Thank you Auth0 team for your help and pointing me to the right direction. :slight_smile:

2 Likes

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.