Lock v11 for Web

Versionv11

Lock is an embeddable login form, configurable to your needs, and recommended for use in single page apps. It enables you to easily add social identity providers, so that your users can login seamlessly using any provider they want.

Embedded login for web uses Cross Origin Authentication. In some browsers this can be unreliable if you do not set up a Custom Domain and host your app on the same domain. Using Custom Domains with Auth0 is a paid feature. If you cannot use Custom Domains, consider migrating to Universal Login.

Lock Installation

You can install Lock v11 via several methods. Select any of the following installation sources that best suit your environment and application.

Installation Sources

Install via npm:

npm install auth0-lock

Install via bower:

bower install auth0-lock

Include via our CDN (Replace .x and .y with the latest minor and patch release numbers from the Lock Github repository:

<!-- Latest minor release -->
<script src="https://cdn.auth0.com/js/lock/11.x/lock.min.js"></script>

<!-- Latest patch release (recommended for production) -->
<script src="https://cdn.auth0.com/js/lock/11.x.y/lock.min.js"></script>

Updating patch versions

It is recommended that production applications use a specific patch version, or at the very least a specific minor version. Regardless of the method by which Lock is included, the recommendation is that the version should be locked down and only manually updated, to ensure that those updates do not adversely affect your implementation. Check the GitHub repository for a current list of releases.

Mobile

If you are targeting mobile audiences, Auth0 recommends that you add the following meta tag to your application's head:

<meta name="viewport" content="width=device-width, initial-scale=1"/>

Bundling Dependencies

If you are using browserify or webpack to build your project and bundle its dependencies, after installing the auth0-lock module, you will need to bundle it with all its dependencies. Examples are available for Browserify and webpack.

Cross-Origin Authentication

Embedded login for web uses Cross Origin Authentication. In some browsers this can be unreliable if you do not set up a Custom Domain and host your app on the same domain. Using Custom Domains with Auth0 is a paid feature. If you cannot use Custom Domains, consider migrating to Universal Login.

Embedding Lock within your application requires cross-origin authentication to be properly configured. Specifically, you need to set the Allowed Web Origins property to the domain making the request. You can find this field in the Application Settings.

Allowed Web Origins

Make sure you read about the limitations of cross-origin authentication before implementing Lock.

Usage

1. Initializing Lock

First, you'll need to initialize a new Auth0Lock object, and provide it with your Auth0 client ID (the unique client ID for each Auth0 application, which you can get from the management dashboard) and your Auth0 domain (for example yourname.auth0.com).

// Initializing our Auth0Lock
var lock = new Auth0Lock(
  'YOUR_CLIENT_ID',
  'YOUR_AUTH0_DOMAIN'
);

2. Authenticating and Getting User Info

Next, listen using the on method for the authenticated event. When the event occurs, use the accessToken which was received to call the getUserInfo method and acquire the user's profile information (as needed). You can also save the token or profile to localStorage for later use.

// Listening for the authenticated event
lock.on("authenticated", function(authResult) {
  // Use the token in authResult to getUserInfo() and save it to localStorage
  lock.getUserInfo(authResult.accessToken, function(error, profile) {
    if (error) {
      // Handle error
      return;
    }

    document.getElementById('nick').textContent = profile.nickname;

    localStorage.setItem('accessToken', authResult.accessToken);
    localStorage.setItem('profile', JSON.stringify(profile));
  });
});

You can then manipulate page content and display profile information to the user (for example, displaying their name in a welcome message).

 <h2>Welcome <span id="nick" class="nickname"></span></h2>

Note that if you are storing the user profile, you will want to JSON.stringify the profile object and then, when using it later, JSON.parse it, because it will need to be stored in localStorage as a string rather than a JSON object.

3. Showing Lock

Here you're showing the Lock widget after the user clicks a login button; you can just as easily show Lock automatically when arriving at a page by just using lock.show(); on page load.

This will show the Lock widget, and paired with the above, you're now ready to handle logins!

document.getElementById('btn-login').addEventListener('click', function() {
  lock.show();
});

Passwordless

Lock's Passwordless Mode is only available in Lock v11.2.0 and later. Please use the latest release of Lock for this feature!

You can use Lock's Passwordless Mode to allow users to authenticate using just an email or mobile number. They will receive the code and then return to input it, or click the link, and they can be authenticated without remembering a password.

In Lock v11, in order to implement Passwordless Mode, you initialize Lock in a slightly different manner, with Auth0LockPasswordless rather than with Auth0Lock:

var lockPasswordless = new Auth0LockPasswordless(
 'YOUR_CLIENT_ID',
 'YOUR_AUTH0_DOMAIN'
);

Passwordless options

Additionally, Lock's Passwordless Mode has a couple of configuration options that are unique to it.

In order to indicate which connection type you would like, you initialize Lock with the allowedConnections option with either email or sms as the value:

var passwordlessOptions = {
  allowedConnections: ['sms']
}

Remember to enable the passwordless connection of your choice in the Dashboard under Connections -> Passwordless, and then to enable it for your application, that way when Lock tries to use it, it is already set up and linked to the application.

If you choose to use email, you have one more option to select - whether you wish your users to receive a code to input, or a "magic link" to use. This is done via the passwordlessMethod option, which takes values of code or link.

var passwordlessOptions = {
  allowedConnections: ['email'],
  passwordlessMethod: 'code'
}

Passwordless example

var passwordlessOptions = {
  allowedConnections: ['email'],
  passwordlessMethod: 'code',
  auth: {
    redirectUrl: 'http://localhost:3000/callback',   
    responseType: 'token id_token',
    params: {
      scope: 'openid email'               
    }          
  }
}

var lockPasswordless = new Auth0LockPasswordless(
 'YOUR_CLIENT_ID',
 'YOUR_AUTH0_DOMAIN',
 passwordlessOptions
);

SSO with embedded authentication

Apps with embedded login must meet two criteria in order to have SSO.

  1. Both of the applications attempting SSO must be first-party applications. SSO with third party applications will not work.
  2. They need to make use of custom domains and have both the applications which intend to have SSO as well as the Auth0 tenant on the same domain. Traditionally, Auth0 domains are in the format foo.auth0.com, but custom domains allow you to use the same domain for each of the applications in question as well as your Auth0 tenant, preventing the risk of CSRF attacks.

Our recommendation is to use Universal Login instead of setting up SSO in embedded login scenarios. Universal Login is the most reliable and stable way to perform SSO, and is the only way to do so if you must use multiple domains for your applications, or use third-party applications.

Error Codes and Descriptions

When Lock v11 is used for embedded login, it employs the /co/authenticate endpoint, which has the following errors.

The error description is human readable. It should not be parsed by any code and it subject to change at any time.

Status Code Description
400 invalid_request Invalid request body. All and only of client_id, credential_type, username, otp, realm are required.
401 unauthorized_client Cross origin login not allowed.
400 unsupported_credential_type Unknown credential type parameter.
400 invalid_request Unknown realm non-existent-connection.
403 access_denied Invalid user credentials.
403 access_denied Wrong email or password.
403 access_denied Authentication error
403 blocked_user Blocked user
401 password_leaked This login attempt has been blocked because the password you're using was previously disclosed through a data breach (not in this application).
429 too_many_attempts Your account has been blocked after multiple consecutive login attempts. We’ve sent you an email with instructions on how to unblock it.
429 too_many_attempts We have detected suspicious login behavior and further attempts will be blocked. Please contact the administrator.

In addition, you can also get a generic 403 error without an error or error_description property. The response body would just include something similar to the following:

Origin https://test.app is not allowed.

Browser Compatibility

Browser compatibility is ensured for Chrome, Safari, Firefox and IE >= 10. Auth0 currently uses zuul along with Saucelabs to run integration tests on each push.

More Examples

The below widget displays brief examples of implementing Auth0 in several ways: Lock as a modal "popup" widget, Lock embedded inline in a div, Lock Passwordless, a custom UI with Auth0.js, and a simple link using the API.

<script src="https://cdn.auth0.com/js/lock/11.6.1/lock.min.js"></script>
<script>
  var lock = new Auth0Lock('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
    auth: {
      redirectUrl: 'https://YOUR_APP/callback',
      responseType: 'code',
      params: {
        scope: 'openid email' // Learn about scopes: https://auth0.com/docs/scopes
      }
    }
  });
</script>
<button onclick="lock.show();">Login</button>
<div id="root" style="width: 320px; margin: 40px auto; padding: 10px; border-style: dashed; border-width: 1px; box-sizing: border-box;">
    embedded area
</div>
<script src="https://cdn.auth0.com/js/lock/11.6.1/lock.min.js"></script>
<script>
  var lock = new Auth0Lock('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
    container: 'root',
    auth: {
      redirectUrl: 'https://YOUR_APP/callback',    // If not specified, defaults to the current page 
      responseType: 'token id_token',
      params: {
        scope: 'openid email'                // Learn about scopes: https://auth0.com/docs/scopes
      }
    }
  });
  lock.show();
</script>
<script src="https://cdn.auth0.com/js/lock/11.6.1/lock.min.js"></script>
<script>
  var lock = new Auth0LockPasswordless('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
        allowedConnections: ['sms'],             // Should match the SMS connection name  
        responseType: 'token id_token',
        auth: {
          redirectUrl: 'https://YOUR_APP/callback',    // If not specified, defaults to the current page 
          params: {
            scope: 'openid email'                // Learn about scopes: https://auth0.com/docs/scopes
          }          
        }
      }
  );

  function open() {
    lock.show();
  };

</script>
<button onclick="window.open();">SMS</button>
<script src="https://cdn.auth0.com/js/lock/11.6.1/lock.min.js"></script>
<script>
  var lock = new Auth0LockPasswordless('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
    allowedConnections: ['email'],           // Should match the Email connection name, it defaults to 'email'     
    passwordlessMethod: 'code',              // If not specified, defaults to 'code'
    responseType: 'token id_token',
    auth: {
      redirectUrl: 'https://YOUR_APP/callback',    // If not specified, defaults to the current page 
      params: {
        scope: 'openid email'                // Learn about scopes: https://auth0.com/docs/scopes
      }          
    }
  });

  function open() {
    lock.show();
  }
</script>
<button onclick="window.open();">Email Code</button>
<button class="signin-google">Sign in with Google (redirect)</button><br>
<button class="signin-google-popup">Sign in with Google (popup)</button><br>
<br><p>--- or ---</p>
<label>Email</label><input type="text" id="email"><br>
<label>Password</label><input type="password" id="password"><br>
<button class="signin-db">Sign in with Email/Password</button>

<script src="https://cdn.auth0.com/js/auth0/9.5.1/auth0.min.js"></script>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
  var webAuth = new auth0.WebAuth({
    domain:         'YOUR_AUTH0_DOMAIN',
    clientID:       'YOUR_CLIENT_ID',
    redirectUri:    'https://YOUR_APP/callback'
  });
  // sign-in with social provider with plain redirect
  $('.signin-google').on('click', function() {
    webAuth.authorize({
      connection: 'google-oauth2' // use connection identifier
    });
  });
  // sign-in with social provider using a popup (window.open)
  $('.signin-google-popup').on('click', function() {
    webAuth.popup.authorize({
      connection: 'google-oauth2'
    });
  });

  $('.signin-db').on('click', function() {
    webAuth.login({
      realm: 'tests',
      username: 'testuser',
      password: 'testpass',
    });
  });
  // Parse the authentication result
  webAuth.parseHash((err, authResult) => {
    if (authResult) {
      // Save the tokens from the authResult in local storage or a cookie
      localStorage.setItem('access_token', authResult.accessToken);
      localStorage.setItem('id_token', authResult.idToken);
    } else if (err) {
      // Handle errors
      console.log(err);
    }
  });
</script>

Next Steps

This document has shown how to use Lock 11 within a Single Page Application (SPA). Take a look at the following resources to see how Lock can be used with other kinds of web apps, or how it can be customized for your needs: