You are here:
Customize the LoginDiscovery Handler
After you create a Login Discovery page, continue setting up passwordless login with an email address or phone number by modifying the autogenerated Apex LoginDiscovery handler. By customizing the handler, you control the login process while Salesforce handles verification. The handler finds users based on the identifier that they provide on the login page, such as their email address. It then checks which verification methods the user has previously registered. The controller logs in the user by whichever method is configured.
- From Setup, in the Quick Find box, enter Apex Classes, and then select Apex Classes.
- Find the autogenerated LoginDiscovery handler class. Its name begins with
AutocreatedDiscLoginHandler, followed by a string of numbers. - Next to the LoginDiscovery handler, click Edit.
- Use these methods to modify the generated code.
UserManagement.registerVerificationMethod- Registers an identity verification method, such as an email address or phone number. Only users can register verification methods. But you and users can deregister them.
UserManagement.deregisterVerificationMethod- Deregisters an existing identity verification method.
Auth.VerificationMethodenum- Represents the available verification methods, which include EMAIL, SALESFORCE_AUTHENTICATOR, SMS, TOTP, and U2F.
UserManagement.formatPhoneNumber- Formats a mobile phone number to ensure that it’s in the format required by
Salesforce. After formatting the phone number, update the mobile field of the
user’s record with the output of
formatPhoneNumber. Site.passwordlessLogin- Logs in a user to a site using an identity verification method that the user previously registered.
For more information about these methods, see these links in the Apex Reference Guide.
PasswordlessLogin Code Example
In this simple code snippet, an Apex controller contains the passwordlessLogin method. For a full implementation, see LoginDiscoveryHandler Example
Implemenation in the Apex Reference Guide
global with sharing class MFILoginController
{
//Input variables
global String input {get; set;}
public String startURL {get; set;}
public List<Auth.VerificationMethod> methods;
public String error;
global MFILoginController()
{
}
global PageReference login()
{
List<User> users = null;
// Empty input
if(input == null || input == '')
{
error = 'Enter Username';
return null;
}
users = [select name, id, email from User where username=:input];
if(users == null || users.isEmpty())
{
error = 'Can\'t find a user';
return null;
}
ID uid = users[0].id;
if (startURL == null) startURL = '/';
// Check which verification methods the user has already registered
TwoFactorMethodsInfo AvailableMethods = [select
HasUserVerifiedMobileNumber,
HasUserVerifiedEmailAddress,
HasSalesforceAuthenticator,
HasTotp,
HasU2F from TwoFactorMethodsInfo where userId=:uid];
// If no verification method is available, prompt the user to enter a password
// and invoke the site.login(usr,pwd) method
// if(AvailableMethods.size() == 0)
// Add verification methods in priority order
methods = new List<Auth.VerificationMethod>();
if(AvailableMethods.HasUserVerifiedMobileNumber)
methods.add(Auth.VerificationMethod.SMS);
if(AvailableMethods.HasUserVerifiedEmailAddress)
methods.add(Auth.VerificationMethod.EMAIL);
if(AvailableMethods.HasSalesforceAuthenticator)
methods.add(Auth.VerificationMethod.
SALESFORCE_AUTHENTICATOR);
if(AvailableMethods.HasTotp)
methods.add(Auth.VerificationMethod.U2F);
if(AvailableMethods.HasU2F)
methods.add(Auth.VerificationMethod.U2F);
return Site.passwordlessLogin(uid, methods, startURL);
}
}

