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 |
- From Setup, in the Quick Find box, enter Apex, and then select Apex Classes.
- Click New.
- Fill the class with your headless registration handler code. You can paste in the code from the example.
- 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.
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}