How to pass data between Webpage and Auth0 Login Page?

Please include the following information in your post:

  • Which SDK this is regarding: auth0-react (auth0.js v9.19 I think)
  • SDK Version: latest
  • Platform Version: NextJS / React (latest version)

I am building a Web App for a customer.

Here are their requirements…

  1. Use Auth0 for managing user login and signup
  2. The login UI should have the same “look and feel” as the rest of the website.
  3. The user should have separate buttons for Login and Signup.
  4. The user should have a “Remember Me” checkbox at login to decide whether to save the username/password on the local machine.

As I searched through the Auth0 Community posts for guidance, I found this repeatedly… “we don’t recommend embedded login. You lose out on a lot of features and increase your attack surface by embedding the login form.”

So if I am to use Auth0 but not use an “embedded login”, it looks like my only choice is to use a Custom Login Page…

  • Branding>Universal Login>Login>HTML

However as I work on this approach, I cannot figure out a way to meet the last 2 requirements…

  • Separate buttons for Login & Signup
  • “Remember Me” checkbox

It seems I could resolve both these issues if we had a way to “pass” information back and fourth between the Website and Auth0.

  • Pass info from the Website to Auth0 (via loginWithRedirect???) to let it know whether to start out with the Login UI or the Signup UI.
  • Pass info from the Auth0 Custom Universal Login page back to the Website to let it know what the “Remember Me” status was.

Can anyone give me ANY suggestions on how to meet these requirements with Auth0?

If not, I will have to present my findings to my client and let them decide whether to go with the “Embedded Login” approach or to drop Auth0 altogether…

Below is my code so far…

Website login.ts file…

import { useAuth0 } from '@auth0/auth0-react';
const {
    user,
    isAuthenticated,
    isLoading,
    getAccessTokenSilently,
    loginWithRedirect,
    logout,
  } = useAuth0();
if (!isAuthenticated) loginWithRedirect();

Universal Login HTML (code saved in https://manage.auth0.com/dashboard/us/--domain--/login_page)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Sign Up / Log In</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
  <style>
    body, html {
      height: 100%;
      background-color: #bacfe8;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }

    .main-container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .ui-box {
      display: flex;
      flex-direction: column;
      background-color: white;
      border-radius: 5px;
      width: 40%;
      padding: 50px;
    }

    .ui-box h4 {
      margin: 10px 0px 25px 0px;
    }

    .form-box {
      display: flex;
      flex-direction: column;
      gap: 25px;
    }

    .error-message {
      display: none;
      white-space: break-spaces;
    }    
    
    .input {
      border-radius: 20px;
    }

    .button {
      background-color: #5385C5;
      color: white;
      height: 50px;
      border-radius: 15px;
    }

    .switch-to {
      font-weight: bold;
      color: black;
    }

    .footer {
      margin-top: 25px;
    }
    
    .margin-zero {
      margin: 0px;
    }

    #logo {
      height: 70px;
      margin-bottom: 25px;
    }

    #terms-checkbox {
      transform: scale(1.5);
    }

    #signup-box {
      display: none;
    }  

    #terms-label {
      display: flex;
      align-items: flex-start;
      gap: 10px;
    }
  </style>
<body>
  <div class="main-container">
    <div id="login-box" class="ui-box">
      <h1 class="margin-zero">Sign in</h1>
      <h4>with your Account</h4>
      <div id="login-error-message" class="alert alert-danger error-message"></div>
      
      <form class="form-box" method="post">
        <div class="form-element">
          <input
            type="email"
            class="form-control input"
            id="email-login"
            placeholder="Your Email">
        </div>
        <div class="form-element">
          <input
            type="password"
            class="form-control input"
            id="password-login"
            placeholder="Password">
        </div>
        <div class="form-element">
          <a href="#" id="forgot-password-login">Forgot Password?</a>
        </div>
        <div class="form-element">
          <button
              type="submit"
              id="btn-login"
              class="btn btn-primary btn-block button">
            SIGN IN
          </button>
        </div>
        <div class="form-element">
          Don't have an account?
          <a class="switch-to" href="#" onclick="switchToSignup()">Sign Up</a>
          <script type="text/javascript">
            function switchToSignup() {
              document.getElementById('signup-box').style.display = 'block';
              document.getElementById('signup-form').reset();
              document.getElementById('login-box').style.display = 'none';
            }
          </script>
        </div>
      </form>
    </div>

    <div id="signup-box" class="ui-box">
      <h1 class="margin-zero">Sign up</h1>
      <h4>Create New Account</h4>
      <div id="signup-error-message" class="alert alert-danger error-message"></div>
      
      <form id="signup-form" class="form-box" method="post">
        <div class="form-element">        
          <input
            type="text"
            class="form-control input"
            id="name-signup"
            placeholder="Your Name">
        </div>
        <div class="form-element">        
          <input
            type="email"
            class="form-control input"
            id="email-signup"
            placeholder="Your Email">
        </div>
        <div class="form-element">          
          <input
            type="password"
            class="form-control input"
            id="password-signup"
            placeholder="Password">
        </div>
        <div class="form-element">          
          <input
            type="password"
            class="form-control input"
            id="password-repeat-signup"
            placeholder="Repeat Password">
        </div>
        <div class="form-element">
          <label id="terms-label" for="terms-checkbox">
            <input type="checkbox" id="terms-checkbox">
            <h5 class="margin-zero">
              I agree to the Terms of Service and Privacy Policy.
            </h5>
          </label>
        </div>
        <div class="form-element">
          <button
            type="button"
            id="btn-signup"
            class="btn btn-default btn-block button">
            CREATE ACCOUNT
          </button>
        </div>
        <div class="form-element">
          Already have an account?
          <a class="switch-to" href="#" onclick="switchToLogin()">Sign In</a>
          <script type="text/javascript">
            function switchToLogin() {
              document.getElementById('login-box').style.display = 'block';
              document.getElementById('signup-box').style.display = 'none';
            }      
          </script>
        </div>
      </form>
    </div>

    <div class="footer">
      Terms of Service
      &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
      Privacy Policy
    </div>
  </div> 

  <!--[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/polyfills/1.0/base64.min.js"></script>
  <script src="https://cdn.auth0.com/js/polyfills/1.0/es5-shim.min.js"></script>
  <![endif]-->

  <script src="https://cdn.auth0.com/js/auth0/9.18/auth0.min.js"></script>
  <script src="https://cdn.auth0.com/js/polyfills/1.0/object-assign.min.js"></script>
  <script>
    window.addEventListener('load', function() {
      var config = JSON.parse(
        decodeURIComponent(escape(window.atob('@@config@@')))
      );

      var leeway = config.internalOptions.leeway;
      if (leeway) {
        var convertedLeeway = parseInt(leeway);
      
        if (!isNaN(convertedLeeway)) {
          config.internalOptions.leeway = convertedLeeway;
        }
      }

      var params = Object.assign({
        overrides: {
          __tenant: config.auth0Tenant,
          __token_issuer: config.authorizationServer.issuer
        },
        domain: config.auth0Domain,
        clientID: config.clientID,
        redirectUri: config.callbackURL,
        responseType: 'code'
      }, config.internalOptions);

      var webAuth = new auth0.WebAuth(params);
      var databaseConnection = 'Username-Password-Authentication';

      // Handle login
      function login(e) {
        e.preventDefault();
        resetError('login-error-message');
        var button = this;
        var email = document.getElementById('email-login').value;
        var password = document.getElementById('password-login').value;
        button.disabled = true;
        webAuth.login({
          realm: databaseConnection,
          email,
          password,
          state: 'YOUR_STATE',
        }, function(err) {
          if (err) displayError('login-error-message', err);
          button.disabled = false;
        });
      }
      document.getElementById('btn-login').addEventListener('click', login);

      // Handle Signup
      function signup(e) {
        e.preventDefault();
        resetError('signup-error-message');
        var button = this;        
        var name = document.getElementById('name-signup').value;
        var email = document.getElementById('email-signup').value;
        var password = document.getElementById('password-signup').value;
        var passwordRepeat = document.getElementById('password-repeat-signup').value;
        var termsChecked = document.getElementById('terms-checkbox').checked;
        if (!name) {displayError('signup-error-message', {description: 'You must provide a name.'}); return;}
        if (!email) {displayError('signup-error-message', {description: 'You must provide an email.'}); return;}
        if (!password) {displayError('signup-error-message', {description: 'You must provide a password.'}); return;}
        if (password != passwordRepeat) {displayError('signup-error-message', {description: 'Passwords do not match.'}); return;}
        if (!termsChecked) {displayError('signup-error-message', {description: 'You must agree to the Terms of Service and Privacy Policy before you can Sign Up.'}); return;}
        button.disabled = true;
        webAuth.redirect.signupAndLogin({
          connection: databaseConnection,
          email,
          password,
          name,
        }, function(err) {
            if (err) displayError('signup-error-message', err);
            button.disabled = false;
        })
      }
      document.getElementById('btn-signup').addEventListener('click', signup);

      // Handle Password Reset Request
      function resetPassword(e) {
        e.preventDefault();
	      var email = document.getElementById('email-login').value;
        if (!email) {displayError('login-error-message', {description: 'You must provide an email.'}); return;}
    		webAuth.changePassword({
      	  connection: databaseConnection,
      	  email,
    		}, function (err, resp) {
      	if(err){
          console.log(err.message);
          alert(err.message);
      	}else{
        	console.log(resp);
          alert(resp);
      	}});
      }
      document.getElementById('forgot-password-login').addEventListener('click', resetPassword);

      function displayError(elementId, err) {
        var errorMessage = document.getElementById(elementId);
        errorMessage.textContent = err.policy || err.description;
        errorMessage.style.display = 'block';
      }

      function resetError(elementId) {
        var errorMessage = document.getElementById(elementId);
        errorMessage.textContent = '';
        errorMessage.style.display = 'none';
      }

    });
  </script>
</body>
</html>

So, first, you can pass data from your app to the login page pretty easily, by doing

loginWithRedirect({
  authorizationParams: {
    someUniqueParam: someValue
  }
})

And you can retrieve it by using

var config = JSON.parse(
  decodeURIComponent(escape(window.atob('@@config@@')))
)
config.extraParams.someUniqueParam // Get the param here

To pass data back to the app is not officially supported, but you can be a little sneaky and do it this way

var config = JSON.parse(decodeURIComponent(window.atob('@@config@@')))

const callbackURL = new URL(config.callbackURL)
callbackURL.searchParams.set('someParam', someValue)
var params = Object.assign(
  {
    // ... other stuff
    redirectUri: callbackURL.toString(),
  },
  config.internalOptions
)

Then you can grab the query string from the URL on redirect.

Not the most elegant way to do this, but it’s there if you need it.

1 Like

Thanks for sharing that with the rest of community!

1 Like

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