Link User Accounts
Link user accounts together to form a primary and secondary relationship. On successful linking, the endpoint returns the new array of the primary account identities.
Auth0 supports the linking of user accounts from various identity providers. This allows a user to authenticate from any of their accounts and still be recognized by your app and associated with the same user profile.
Availability varies by Auth0 plan and login method
Both the login implementation you use and your Auth0 plan or custom agreement affect whether this feature is available. To learn more, read New Universal Login vs. Classic Universal Login and Pricing.
Auth0 treats all identities as separate by default. For example, if a user logs in first against the Auth0 database and then via Google or Facebook, these two attempts would appear to Auth0 as two separate users.
There are three ways to link accounts:
Use the Account Link extension
Use the Management API
Use Auth0.js
Use the tabs below to see the details for each option.
Account Link extension
Install and configure the Account Link Extension extension in the Dashboard to prompt users that may have created a second account to link the new account with their old one on their first login. The user can choose to either link the two accounts or keep them separate if it was intentional.
Management API endpoint
The Auth0 Management API provides the Link a user account endpoint, which can be invoked in two ways:
- User initiated account linking using Access Tokens with the
update:current_user_identities
scope - Server-side account linking using Access Token that contains the
update:users
scope
User initiated client-side account linking
For user initiated account linking from client-side code, use an Access Token that contains the following items in the payload:
update:current_user_identites
scopeuser_id
of the primary account as part of the URL- ID Token of the secondary account must be signed with
RS256
and anaud
claim identifying the client that matches the value of the requesting Access Token'sazp
claim.
An Access Token that contains the update:current_user_identities
scope can only be used to update the information of the currently logged-in user. Therefore, this method is suitable for scenarios where the user initiates the linking process.
{
"method": "POST",
"url": "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities",
"httpVersion": "HTTP/1.1",
"headers": [{
"name": "Authorization",
"value": "Bearer ACCESS_TOKEN"
},
{
"name": "content-type",
"value": "application/json"
}],
"postData" : {
"mimeType": "application/json",
"text": "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}"
}
}
Was this helpful?
Server-side account linking
For server-side account linking, use an Access Token that contains the following items in the payload:
update:users
scopeuser_id
of the primary account as part of the URLuser_id
of the secondary account- ID Token of the secondary account must be signed with
RS256
and anaud
claim identifying the client that matches the value of the requesting Access Token'sazp
claim.
Access Tokens that contain the update:users
scope can be used to update the information of any user. Therefore, this method is intended for use in server-side code only.
{
"method": "POST",
"url": "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities",
"httpVersion": "HTTP/1.1",
"headers": [{
"name": "Authorization",
"value": "Bearer ACCESS_TOKEN"
},
{
"name": "content-type",
"value": "application/json"
}],
"postData" : {
"mimeType": "application/json",
"text": "{\"provider\":\"SECONDARY_ACCOUNT_PROVIDER\", \"user_id\": \"SECONDARY_ACCOUNT_USER_ID\"}"
}
}
Was this helpful?
The SECONDARY_ACCOUNT_USER_ID
and SECONDARY_ACCOUNT_PROVIDER
can be deduced by the unique ID of the user. For example, if the user ID is google-oauth2|108091299999329986433
, set the google-oauth2
part as the provider
, and the 108091299999329986433
part as the user_id
at your request.
Instead of the provider
and user_id
, you can send the secondary account's ID Token as part of the payload:
{
"method": "POST",
"url": "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities",
"httpVersion": "HTTP/1.1",
"headers": [{
"name": "Authorization",
"value": "Bearer ACCESS_TOKEN"
},
{
"name": "content-type",
"value": "application/json"
}],
"postData" : {
"mimeType": "application/json",
"text": "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}"
}
}
Was this helpful?
Auth0.js library
You can use the Auth0.js library.
First, you must get an Access Token that can be used to call the Management API. You can do it by specifying the https://{yourDomain}/api/v2/
audience when initializing Auth0.js. You will get the Access Token as part of the authentication flow. Alternatively, you can use the checkSession
method.
Once you have the Access Token, you can create a new auth0.Management
instance by passing it the account's Auth0 domain, and the Access Token.
To learn more, read Auth0.js > User management.
Add missing information with Rules
When a user logs in, apps receive user information from the primary identity. Auth0 does not attempt to automatically complete missing profile fields with information from the secondary identities. For example, if the primary identity comes from a database connection and is missing the given_name
and family_name
properties, and the secondary identity comes from a Google social connection that includes the first and last name of the user, then the application will not receive data contained in the second identity.
To add missing information to primary identities with information from secondary identities, you can write a rule like the following example:
function(user, context, callback) {
const propertiesToComplete = ["given_name", "family_name", "name"];
// go over each property and try to get missing
// information from secondary identities
for(var property of propertiesToComplete) {
if (!user[property]) {
for(var identity of user.identities) {
if (identity.profileData && identity.profileData[property]) {
user[property] = identity.profileData[property];
break;
}
}
}
}
callback(null, user, context);
}
Was this helpful?