Skip to content

Latest commit

 

History

History
139 lines (129 loc) · 6.42 KB

HOWTO-configure-auth0.md

File metadata and controls

139 lines (129 loc) · 6.42 KB

How to configure Auth0 for authentication

There are two authentication backends supported for Spoke. The first and default is using https://auth0.com. This service allows support for e.g. Google authentication and others, and supports things like password resets and account management separate from Spoke.

The alternative and default for development environments is local login, where passwords are hashed locally in the database and resets, etc are administered all within Spoke. While good for development, we believe Auth0 still provides better security for production environments. Below are the steps to configure Spoke for Auth0.

Configuration Steps

  1. First configure the environment variable PASSPORT_STRATEGY=auth0 in .env or wherever to configure Spoke environment variables.
  2. Create an Auth0 account. In your Auth0 account, go to Applications, click on Default App and then grab your Client ID, Client Secret, and your Auth0 domain (should look like xxx.auth0.com). Add those inside your .env file (AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_DOMAIN respectively).
  3. Run yarn dev to create and populate the tables.
  4. In your Auth0 app settings, set the following (Note: for development use http://localhost:3000 instead of https://yourspoke.example.com):
    • Allowed Callback URLs - https://yourspoke.example.com/login-callback
    • Allowed Web Origins - https://yourspoke.example.com
    • Allowed Logout URLs - https://yourspoke.example.com/logout-callback
    • Allowed Origins (CORS) - https://yourspoke.example.com
  5. In Advanced Settings, under the OAuth section, turn off 'OIDC Conformant'.
  6. Navigate to Actions Library.
  7. Click "Build Custom".
  8. Enter the following fields:
    • Name: Spoke Action
    • Trigger: Login / Post Login
    • Runtime: <DEFAULT>
  9. Click "Create".
  10. In the code block of the Actions Code Editor, update the exports.onExecutePostLogin code as follows:
exports.onExecutePostLogin = async (event, api) => {
    api.idToken.setCustomClaim("https://spoke/user_metadata", event.user.user_metadata);
};
  1. Click Deploy.

  2. Navigate to Actions Flows.

  3. Click "Login".

  4. Add "Spoke Action" to the Login flow.

  5. Click "Apply".

  6. Update the Auth0 Universal Landing page, click on the Customize Login Page toggle, and copy and paste following code in the drop down into the Default Templates space:

    Code to paste into Auth0
    <!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.34.2/lock.min.js"></script>
      <script>
        // Decode utf8 characters properly
        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;
    
        // 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: https://auth0.com/docs/custom-domains/additional-configuration
          // configurationBaseUrl: config.clientConfigurationBaseUrl,
          // overrides: {
          //   __tenant: config.auth0Tenant,
          //   __token_issuer: 'YOUR_CUSTOM_DOMAIN'
          // },
          assetsUrl:  config.assetsUrl,
          allowedConnections: ['Username-Password-Authentication'],
          rememberLastLogin: !prompt,
          language: language,
          languageDictionary: {
            title: 'Spoke',
            signUpTerms: 'I agree to the <a href="YOUR_TOS_LINK_HERE" target="_new">terms of service</a> and <a href="YOUR_PRIVACY_POLICY_LINK_HERE" target="_new">privacy policy</a>.'
          },
          mustAcceptTerms: true,
          theme: {
            logo:            '',
            primaryColor:    'rgb(83, 180, 119)'
          },
          additionalSignUpFields: [{
            name: 'given_name',
            icon: 'https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png',
            placeholder: 'First Name'
          }, {
            name: 'family_name',
            placeholder: 'Last Name',
            icon: 'https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png'
          }, {
            name: 'cell',
            placeholder: 'Cell Phone',
            icon: 'https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png',
            validator: (cell) => ({
              valid: cell.length >= 10,
              hint: 'Must be a valid phone number'
            })
          }],
          prefill: loginHint ? { email: loginHint, username: loginHint } : null,
          closable: false,
          defaultADUsernameFromEmailPrefix: false,
          // Uncomment if you want small buttons for social providers
          // socialButtonStyle: 'small'
        });
        lock.show();
      </script>
    </body>
    </html>
  7. Replace YOUR_TOS_LINK_HERE with the link to your Terms of Service and replace YOUR_PRIVACY_POLICY_LINK_HERE with the link to your Privacy Policy