Passing data to the hosted login page: With Solution!

Motivation

Auth0 allows for using the Universal Login Page (ULP) as a nice way to unify various sites. This feature also allows for hosting some custom HTML to specially configure various things.

The issue one runs into is that the recommended manner for interacting with the ULP is to direct a user to the /authorize endpoint. Unfortunately, the /authorize endpoint strips out most query parameters which could then be passed down to something like the /login page etc.

This makes doing something like defaulting to the signup tab, or showing an error message difficult as you can’t pass extra information via query params (things like localStorage or cookies can’t work due to cross origin etc.).

Purely creating this issue as a way to document a solution which worked for our team in response to the above linked issue (would have commented on the other but it’s closed…)

Original Issue

Proposed Solution

Our team found that a novel way to pass whatever parameters/data into the hosted HTML pages was to add additional arguments to the urlencoded redirect_uri.

Since we are in charge of this url, we can pass any additional query parameters to that and then ignore them on our web server (most times additional query params are just ignored by default anyways).

Code

Below is the code we used in our hosted /login page to see whether we should default lock.js to Signup instead of the default Login. The redirect_uri here gets an extra query params of isSignup=1.

ex: https://redirect_url.com/?isSignup=1 => ?redirect_uri=https%3A%2F%2Fredirect_url.com%2F%3FisSignup%3D1

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Sign In with Auth0</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <!--[if IE 8]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/ie8/0.2.5/ie8.js"></script>
    <![endif]-->

    <!--[if lte IE 9]>
      <script src="https://cdn.auth0.com/js/base64.js"></script>
      <script src="https://cdn.auth0.com/js/es5-shim.min.js"></script>
    <![endif]-->

    <script src="https://cdn.auth0.com/js/lock/11.15/lock.min.js"></script>
    <script>
      // Decode utf8 characters properly
      function getQueryVariable(href, variable) {
        const [_, query] = href.split('?');
        if (!query) {
          return false;
        }

        const vars = query.split('&');
        for (var i = 0; i < vars.length; i++) {
          var [key, value] = vars[i].split('=');
          if (decodeURIComponent(key) == variable) {
            return decodeURIComponent(value);
          }
        }
        return false;
      }

      function initialScreen() {
        const redirectUri = getQueryVariable(window.location.href, 'redirect_uri');
        const isSignup = getQueryVariable(redirectUri, 'isSignup');
        if (isSignup) {
          return 'signUp';
        }
        return 'login';
      }

      var config = JSON.parse(decodeURIComponent(escape(window.atob('@@config@@'))));
      config.extraParams = config.extraParams || {};
      var connection = config.connection;
      var prompt = config.prompt;
      var languageDictionary;
      var language;

      if (config.dict && config.dict.signin && config.dict.signin.title) {
        languageDictionary = {title: config.dict.signin.title};
      } else if (typeof config.dict === 'string') {
        language = config.dict;
      }
      var loginHint = config.extraParams.login_hint;
      var colors = config.colors || {};

      // Available Lock configuration options: https://auth0.com/docs/libraries/lock/v11/configuration
      var lock = new Auth0Lock(config.clientID, config.auth0Domain, {
        auth: {
          redirectUrl: config.callbackURL,
          responseType:
            (config.internalOptions || {}).response_type ||
            (config.callbackOnLocationHash ? 'token' : 'code'),
          params: config.internalOptions,
        },
        /* 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: config.icon,
          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'
        initialScreen: initialScreen(),
      });

      if (colors.page_background) {
        var css =
          '.auth0-lock.auth0-lock .auth0-lock-overlay { background: ' +
          colors.page_background +
          ' }';
        var style = document.createElement('style');

        style.appendChild(document.createTextNode(css));

        document.body.appendChild(style);
      }

      lock.show();
    </script>
  </body>
</html>

Suggested Musical Pairing

2 Likes

@sparosequist @ttchuah @arosequist hope this helps!

Thanks for sharing, @mannimal09!

A similar question was in here just two days ago, see related thread (second question of the two in the thread):

btw: suggested musical pairing works well. :headphones::headphones::headphones:

Hello,

I wanted to chime in and suggest a better way of passing custom params into the hosted login page.

It is true that if you pass extra params into the authorize URL, these will not be present in the login URL users are redirected to. However, they will be present in the config.extraParams object.

e.g., if you make a call like “/authorize?moreParams=param” then the config.extraParams object will contain “moreParams: param”.

This is the preferred way of doing this because in the future, params are likely to be stripped from the redirect URL. While I can’t guarantee that the params passed into the authorize endpoint will always be available, it is not something we currently plan on getting rid of.

2 Likes

Thanks a lot for sharing that knowledge here @thomas.osborn!

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