Auth0 Home Blog Docs

Custom fields on universal login page but not passed to JWT


#1

Ive added a field called “displayname” which shows up in the hosted universal login page. However the field isnt passed to the JWT so I have no way of accessing it.

Note - Im not using the “Requires Username” in the database connection as I dont want display names to have to be unique.

<!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.3/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;
    
    var lock = new Auth0Lock(config.clientID, config.auth0Domain, {
      auth: {
        redirectUrl: config.callbackURL,
        responseType: (config.internalOptions || {}).response_type ||
          (config.callbackOnLocationHash ? 'token' : 'code'),
        params: config.internalOptions
      },
      assetsUrl:  config.assetsUrl,
      allowedConnections: connection ? [connection] : null,
      rememberLastLogin: !prompt,
      language: language,
      languageDictionary: languageDictionary,
      prefill: loginHint ? { email: loginHint, username: loginHint } : null,
      closable: false,
      defaultADUsernameFromEmailPrefix: false,
      // uncomment if you want small buttons for social providers
      // socialButtonStyle: 'small'
      additionalSignUpFields: [{
        name: "displayname",
        placeholder: "display name",
        validator: function(displayname) {
          return {
             valid: displayname.length >= 3,
             hint: "That name is too short"
          };
        }
      }]
    });

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

#2

Ive also tried using the Hook, but again I dont see any new fields in the generated JWT:

module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token['https://foo.com/claim'] = 'bar';
  access_token.scope = scope;
  access_token.scope.push('extra');
  cb(null, access_token);
};

#3

I needed to add a rule in addition to adding the field to the universal login page.

The rule seems not to work unless you use a namespace:

function (user, context, callback) {
  user.user_metadata = user.user_metadata || {};
  if (user.user_metadata.displayname) {
    const namespace = 'https://MYSITE.com/';
  	context.idToken[namespace + 'display_name'] = user.user_metadata.displayname;
  }
  callback(null, user, context);
}