403 Invalid state error from custom login page

Problem statement

With the Classic Universal Login enabled, the following features have been configured:

  • ‘Customize Login Page’ is enabled under Branding > Universal Login > Advanced Options > Login.
  • Custom HTML has been added, including additional javascript files that are hosted in a non-Auth0 related CDN.
  • Using the Auth0.js library in the Customized Login Page
    With the above configurations, end users see the error ‘invalid state’ when attempting to log in to a given connection.

Symptoms

The state value passed to POST /usernamepassword/login does not match the state value generated at GET /login (e.g. hkF…).

Steps to Reproduce

Remove config.internalOptions from the params object that’s passed to webAuth.login() in a custom login page using Auth0.js.

Troubleshooting

Review the custom login page scripts and confirm the config option is being properly parsed and that the proper values are assigned to properties of the params object that’s passed to the login methods, including config.internalOptions.

Cause

When the config.internalOptions object, which includes the state value generated at GET /login, is not included in the params object, the correct state is not passed to the Auth0.js login methods. This results in the methods generating a new state value that does not match the original /login state.

Solution

Ensure that the config.internalOptions object is included in the params object like so:

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