Auth0 Home Blog Docs

Signup with user_metadata

Hi,
I’m already using “Universal Login” to login using Social as well as DB connection as well. I’m using auth0.js v9 SDK.

Question 1. How to achieve signup to DB connection using Universal Login?
Question 2. How to signup and provide user_metadata at the same time?

Thanks,
Ruben

Hi @berlioz

Q1: with what exactly are you struggling here? When the user comes to the Universal Login Page, the user can switch between login and signup there by clicking the signup link (depending whether you use the Classic or New ULP, it’s either a link or a tab). In regards to how you make the authorize call towards Auth0, there is not difference between login and signup.

Q2: shall this meta data coming from a user input field, or automatically added by to some logic? If via user input, you can use additional signup fields, see https://auth0.com/docs/libraries/lock/v11/configuration#additionalsignupfields-array- (this only works with the Classic Universal Login Page, not the new one), otherwise you can use a Rule to add metadata (the rule would use the updateUserMetadata method of the node-sdk for this).

Hi @mathiasconradt, thanks for response!

Q1. oh, indeed, i didn’t even see the signup link down below in the new ULP. But still I’d like to trigger the signup screen using the auth0.js v9 sdk, to make usability more streamlined.

Q2. I’m trying to add plan details to newly registered users. Can those fields be added for social accounts also? I’m comfortable writing a rule to populate app_metadata, but do do i pass the additional details to the rule? Also, I’m using auth0.js v9 (not the Lock). how do i pass those fields with it?

Q1: if you’re using the Classic Universal Login Page (ULP) and not the New ULP, see my answer here:

I’m trying to add plan details to newly registered users

Q2: Is the plan something the user selects before he signs up (something you know when the user reaches the Auth0 signup page), or something he should select on the Auth0 signup page, or even afterwards?

@mathiasconradt, I’m using the New ULP. How much of those is relevant to the New ULP?

My user already selected the plan on in the first place before getting redirected to the New ULP. How can I pass those details to the the app_metadata?

Also, how would callback URLs help? Could you please elaborate bit more on this?

Thanks!

Q1: it doesn’t (yet) work with the New ULP (though it’s been added to the product backlog as feature request, no ETD). Therefore my previously linked thread doesn’t apply, neither do the callback URLs help here.

Q2: see the approach here, it’s an example referring to the auth0.js / authorize method:

Pass the plan infos like this and read them out in the Rule again (and store them as app_metadata).

@mathiasconradt, regarding the extra fields I looked to auth0.js documentation and could not find any mention of authParamsMap.

I tried to set parameters as in the other thread like this:

    auth0.authorize({
        connection: "google-oauth2",
        initialScreen: 'signUp',
        authParamsMap: {'referrerId': 'abc123'}
    });

and tried to access it from the rule:

user.app_metadata.referrer_id = context.request.query.auth_params_map.referrer_id;

But I get error:

 Cannot read property 'referrer_id' of undefined. Please log out and try again.

Are you sure this is supposed to work with auth0.js v9 sdk?

Are you sure this is supposed to work with auth0.js v9 sdk?

Yes, I am very sure :slight_smile:

There is no app_metadata object for a new user unless it’s ever been set before (such as in a previous rule for example, which isn’t the case for you).
Therefore, try this additional line before:

user.app_metadata = user.app_metadata || {};
user.app_metadata.referrer_id = context.request.query.auth_params_map.referrer_id;

Also, see this example https://auth0.com/docs/rules/guides/metadata#update-app_metadata on how to persist the app_metadata in the user store. Because just assigning it alone is volatile.

@mathiasconradt, I hate to tell that, but something is definitely off :slight_smile:

Here is the actual rule:

function (user, context, callback) {
    Promise.resolve()
        .then(() => {
            user.app_metadata = user.app_metadata || {};
            user.app_metadata.referrer_id = context.request.query.auth_params_map.referrer_id;
            return auth0.users.updateAppMetadata(user.user_id, user.app_metadata);
        })
        .then(() => {
            callback(null, user, context);
        })
        .catch(reason => {
            console.log(reason);
            callback(reason);
        });
} 

The error Cannot read property ‘referrer_id’ of undefined is related to the right side of the operator, not the left side. The context.request.query does not contain auth_params_map.

I tested your exact rule code and I get the referrerId just fine.

Can you add the line and debug the rule, see what’s in the logs. (Needs Real-time webtask log extension).

console.log('context: ' + JSON.stringify(context) );

and check what’s in there.

Also: please try in a new/incognito browser window, the user being logged out, and do not just reload (F5 / browser reload) the existing app when trying.
(I was able to reproduce an issue with the error message you mentioned under certain circumstances, but that seems to be related with reloading the SPA in the browser and/or renewing the token when the user already has an existing session.)

But my otherwise successful test (using an older Vue.js Quickstart that uses the auth0.js) as follows:

    webAuth.authorize({
      authParamsMap: {'referrerId': 'abc123'}
    });

image

Update:

Regarding

I was able to reproduce an issue with the error message you mentioned under certain circumstances, but that seems to be related with reloading the SPA in the browser and/or renewing the token when the user already has an existing session.

If you need to have the plan details in this occasion (when doing a checkSession which you probably don’t need or want, as the parameter should at that time already been stored in the user profile , and you’d most likely also return it in the ID token) available in the rule again, you’d need to pass it in the checkSession method as well (I assume you have this somewhere in the code?), like this:

webAuth.checkSession({
    authParamsMap: {'referrerId': 'abc123'}
}

However, I don’t think this makes sense to have it there, because you don’t need it at that point anymore (you only need to pass the plan details at first signup).
Therefore, instead, just add a check in the rule and don’t do anything if the parameter is missing.

if (context.request.query.auth_params_map) {
     user.app_metadata.referrer_id = context.request.query.auth_params_map.referrer_id;
    // ....
}

@mathiasconradt, I got it working by adding a check for:

 if (context.request.query.auth_params_map) {

That query object is not present on the second time the rule is called.

The last issue I’m having is that “initialScreen: ‘signUp’,” is not honored. The New ULP is opened in the Login page by default. It was the same behavior with the classic ULP.

1 Like

That query object is not present on the second time the rule is called.

Yes it depends if there is an existing user session or not, and how that’s handled in the client application. But glad it now works for you.

The last issue I’m having is that “initialScreen: ‘signUp’

This doesn’t work with the New ULP. There’s currently no mechanism to preselect the sign up page by default, as it was possible with the classic ULP. But it’s in the product backlog.

(initialScreen should work fine with the Classic ULP though)

@mathiasconradt, The rule part is sorted out.

I changed to Classic ULP and initialScreen: ‘signUp’ is still not navigating to signup screen.
Here is what my request looks like:

https://xxx.auth0.com/authorize?initial_screen=signUp&response_type=token%20id_token&redirect_uri=http://xxx&scope=read%3Acurrent_user%20profile%20email%20openid&audience=http://xxx&nonce=xxx&auth0Client=xxx&client_id=xxx&state=xxx

The initialScreen parameter is a parameter used with Lock (within the customised hosted login page at Auth0) , not as parameter with the auth0.js authorize call.

See examples

@mathiasconradt, I’m not using Lock, I’m using Auth0.js v9. This is honestly very frustrating. Three client-side libraries are provided: Auth0-spa-js, Auth.js v9 and Lock, nut none provide a complete solution. Two versions of ULP cause another level of complexity by not having all features of old one supported by the new one.

Anyways, the Lock somehow translates the initialScreen parameter into some URL argument to
https://xxxx.auth0.com/login url query parameters, right? Shouldn’t it be possible to set corresponding argument manually to cause the UI to show Sign Up first?

Thanks

I changed to Classic ULP

@berlioz If you’re using the Classic ULP and the default template, you’re automatically using Lock (on Auth0 side) , regardless of using the auth0.js of the client application side.

I’m referring to the Lock library / widget in the hosted Classic ULP (Dashboard > Universal Login Page > Login tab > Customize Login Page > used Lock widget inside this template shown there - > this is where the initialScreen option needs to go) , not talking about an embedded Lock in your client application.
(The hosted Classic ULP uses the Lock.js internally)

The linked threads show examples. They also use auth0.js on the client app side.

Two versions of ULP cause another level of complexity by not having all features of old one supported by the new one.

Yes, the new ULP doesn’t offer all features of the classic yet, because it’s newer. These will eventually follow over time. The difference or missing features are documented in the docs. Benefits of the New ULP are a streamlined UI and not relying on Javascript.

Lock somehow translates the initialScreen parameter into some URL argument to
https://xxxx.auth0.com/login url query parameters, right?

No, this url pattern only exists with the New ULP, not in the Classic ULP, because there, the switch between login and signup happens via tab switch in the UI on the same URL, no different URL.
initialScreen has no affect / isn’t available with the New ULP. (Internally, initialScreen only brings the signup tab to the front via Javascript, in the Lock within Classic ULP)

Got it. Had no idea about another Lock running within Classic ULP.
I have it working now with Classic ULP. But you guys have some work to do to streamline the process :slight_smile:

@mathiasconradt, thanks for your help on this!

1 Like

Thanks a lot for the feedback @berlioz! Let us know if you have any other questions!

1 Like

@berlioz Glad it’s working, and there should be a way to do the same with the New ULP at some point. I agree, it could be made easier or more obvious, taking it as feedback back to the product team.

1 Like

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