Create a Headless Registration Handler

Create an Apex class for your registration handler. You reference this Apex class when you configure Experience Cloud settings on the Login & Registration page.
Available in: both Salesforce Classic (not available in all orgs) and Lightning Experience
Available in: Enterprise, Unlimited, and Developer Editions

  1. From Setup, in the Quick Find box, enter Apex, and then select Apex Classes.
  2. Click New.
  3. Fill the class with your headless registration handler code. You can paste in the code from the example.
  4. Save the class, and note its name.

Example

Here’s an example headless registration handler. This registration handler creates a user and links it to the account and profile that you created earlier in this guide.

This sample code is for demonstration only. Always test code before deploying it to a production environment.

Note

1/*
2 * Sample Headless Self Registration Handler class for Headless Identity implementation
3 */
4
5global class HeadlessSelfRegistrationHandler implements Auth.HeadlessSelfRegistrationHandler{
6    static final String headless_account = 'My Account';
7    
8    // Creates a Standard salesforce or a community user
9    global User createUser(Id profileId, Auth.UserData data, String customUserDataMap, String experienceId, String password){
10        User u = new User();
11        //Ensures the user will save as all required fields are pre-filled in with dummy values
12        prepareUserData(data, u);
13
14        //Get the Account, and create it if one is not already present. 
15        Account a;
16        List<Account> accounts = [SELECT Id FROM Account WHERE name='My Account'];
17        if(accounts.isEmpty()) {
18            a = new Account(name = headless_account);
19            insert(a);
20        } else {
21            a = accounts[0];
22        }
23        
24        handleCustomData(customUserDataMap); 
25        
26        // Create the Contact
27        Contact c = new Contact();
28        c.accountId = a.Id;
29        c.firstName = u.firstName;
30        c.lastName = u.lastName;
31        insert(c);
32        
33        //Associate the Contact to the user along with the profile. 
34        u.profileId = profileId;
35        u.contactId = c.Id;
36        return u;
37    }
38    
39    /*
40     * We support the ability to pass in complex structures in the custom user data map
41     * You can build Apex classes that represent your complex structure
42     * Then deserialize that structure into your Apex class
43     * In this case we have a class at the bottom of this file called "ContactInformation"
44     * This class deserializes the incoming request and prints out the fields
45     * */ 
46    void handleCustomData(String customUserDataMap) {
47        System.debug('Custom Data: ' + customUserDataMap); 
48        ContactInformation contactInfo = null; 
49        try {
50            contactInfo = (HeadlessSelfRegistrationHandler.ContactInformation)JSON.deserialize(customUserDataMap, HeadlessSelfRegistrationHandler.ContactInformation.class);
51            System.debug('ContactInfo.mobilePhone: ' + contactInfo.mobilePhone); 
52            System.debug('ContactInfo.streetAddress: ' + contactInfo.streetAddress); 
53            System.debug('ContactInfo.city: ' + contactInfo.city); 
54            System.debug('ContactInfo.state: ' + contactInfo.state); 
55        } catch (Exception e) {
56            System.debug('JSON was not formed correctly for the apex class'); 
57        }
58        
59        
60    }
61    
62    /*
63	* This method handles filling user data that is required by Salesforce but is not passed in during registration
64    * It is not strictly necessary but helpful as it centralizes the management of unnecessary fields to the IDP instead of the client. 
65	*/
66    void prepareUserData(Auth.UserData data, User u){
67        
68        String name, firstName, lastName, username, alias, email;
69        
70        System.debug('----> Passed In User Information');
71        System.debug('Email: ' + data.email);
72        System.debug('First Name: ' + data.firstName);
73        System.debug('Last Name: ' + data.lastName);
74        
75        for(String key : data.attributeMap.keySet())
76        {
77            System.debug('key: ' + key + ' value: ' + data.attributeMap.get(key));
78        }
79        // Initialize the attributes required to create a new user with dummy values
80        // in case they are not provided by the Auth Provider
81        firstName = 'change-me';
82        lastName = 'change-me';
83        email = 'change@me.com';
84        if(data.email != null && data.email != '')
85            email = data.email;
86        if(data.firstName != null && data.firstName != '')
87            firstName = data.firstName;
88        if(data.LastName != null && data.lastName != '')
89            lastName = data.lastName;
90        if(data.attributeMap.containsKey('full_name'))
91            name = data.attributeMap.get('full_name');
92        if(data.attributeMap.containsKey('name'))
93            name = data.attributeMap.get('name');
94        if(firstName == 'change-me' && name != '')
95            firstName = name.substringBefore(' ');
96        if(lastName == 'change-me' && name.substringAfter(' ') != '')
97            lastName = name.substringAfter(' ');
98        
99        // Generate a random username
100        Integer rand = Math.round(Math.random()*100000000);
101        if(data.attributeMap.containsKey('username')){
102            username = data.attributeMap.get('username');
103        }else{
104            username = lastName + '.' + rand + '@social-sign-on.com';
105        }
106        alias = firstName;
107        
108        //Alias must be 8 characters or less
109        if(alias.length() > 8)
110            alias = alias.substring(0, 8);
111        u.username = username;
112        u.email = email;
113        u.lastName = lastName;
114        u.firstName = firstName;
115        u.alias = alias;
116        u.languagelocalekey = UserInfo.getLocale();
117        u.localesidkey = UserInfo.getLocale();
118        u.emailEncodingKey = 'UTF-8';
119        u.timeZoneSidKey = 'America/Los_Angeles';
120    }
121    
122    /*
123     * Apex Class Representation of Contact Information 
124     * which was passed in the custom data map
125     * */ 
126    global class ContactInformation {
127        String mobilePhone;
128        String streetAddress;
129        String city; 
130        String state;
131        Boolean privacyPolicy; 
132    }
133}