Email/SMS Authentication
Register or login a user using One-Time Passcodes or Magic Links on Android
Your Passage app will default to One-Time Passcodes, but you can also choose to use Magic Links instead. Both One-Time Passcodes and Magic Links can be sent via email or phone (depending on what kind of identifier your user provides).
Passage highly recommends using One-Time Passcodes over Magic Links, as they are easier to implement, more secure, and a better user experience.
One-Time Passcode (OTP)
Register with OTP
Here's an example of how to register a user using OTPs.
Send a new registration OTP to user
Call passage.oneTimePasscode.register
to send your user a new passcode for registration. A successful call will return a OTP id, which you'll need to finish user registration later.
suspend fun sendRegistrationOTP(identifier: String) {
try {
val otpId = passage.oneTimePasscode.register(identifier).otpId
// Returns an OTP id which you'll need later for completing user registration.
} catch (e: OneTimePasscodeRegisterException) {
when (e) {
is OneTimePasscodeInvalidIdentifierRegisterException -> {
// Alert user their email or phone number was invalid
}
}
}
}
Activate registration OTP
When the user inputs their OTP into your app, you'll send their input string along with the OTP id through passage.oneTimePasscode.activate
.
suspend fun authenticateOTPUser(otp: String, otpId: String) {
try {
// Where "otp" is the code the user input and "otpId" is from passage.newRegisterOneTimePasscode
passage.oneTimePasscode.activate(otp, otpId)
// Do authenticated stuff
} catch (e: OneTimePasscodeActivateException) {
when (e) {
is OneTimePasscodeActivateInvalidRequestException -> {
// Alert user their passcode was invalid
}
}
}
}
For the best user experience, we recommend implementing the SMS Retriever API (opens in a new tab) for users that authenticate with a phone number. This enables the user to tap a button to fill out the code input, rather than requiring them to type each number.
Log in with OTP
Here's an example of how to log in a user using OTPs.
Send a new login OTP to user
Call passage.oneTimePasscode.login
to send your user a new passcode for logging in. A successful call will return a OTP id, which you'll need to finish user login later.
suspend fun sendLoginOTP(identifier: String) {
try {
val otpId = passage.oneTimePasscode.login(identifier).otpId
// Returns an OTP id which you'll need later for completing user login.
} catch (e: OneTimePasscodeLoginException) {
when (e) {
is OneTimePasscodeInvalidIdentifierLoginException -> {
// Alert user their email or phone number was invalid
}
}
}
}
Activate login OTP
The method for activating a login OTP is the same as activating a registration OTP. See above example.
Magic Links
Register with Magic Link
Here's an example of how to register a user using Magic Links.
Send a new registration Magic Link to user
Call passage.magicLink.register
to send your user a new Magic Link for registration. A successful call will return a Magic Link id, which you'll need to finish user registration later.
suspend fun sendRegistrationMagicLink(identifier: String) {
try {
val magicLinkId = passage.magicLink.register(identifier).id
// Returns a Magic Link id which you'll need later to check the status of the Magic Link.
} catch (e: MagicLinkRegisterException) {
when (e){
is MagicLinkInvalidIdentifierRegisterException -> {
// Alert user their email or phone number was invalid
}
}
}
}
Activate magic Link
If the user opens the Magic Link from the same Android device and you’ve setup App Linking correctly, that link will open your Android app and you can grab the Magic Link string from your Activity’s onNewIntent
method (see example here). Then you can call passage.magicLinkActivate(userMagicLink)
to authenticate the user.
class MainActivity: AppCompatActivity() {
//..
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val magicLink = intent?.data?.getQueryParameter("psg_magic_link") ?: return
passage.magicLink.activate(magicLink) ?: return
// Do authenticated stuff
}
}
Check Magic Link status
If the user opens the Magic Link on a different device or you have not setup App Linking, it is up to your web front end to handle and activate the Magic Link. In this case, you’ll need to continually check the status of the link in your Android app. Once the Magic Link has been activated by the web front end, passage.getMagicLinkStatus
will return a PassageAuthResult
and your user will be authenticated.
suspend fun checkMagicLinkStatus(magicLinkId: String) {
try {
// Where "magicLinkId" is from passage.newRegisterMagicLink
passage.magicLink.status(magicLinkId) ?: return
// Do authenticated stuff
} catch (e: GetMagicLinkStatusException) {
when (e) {
is GetMagicLinkStatusInvalidException -> {
// Alert user that the magic link is no longer valid
}
}
}
}
Log in with Magic Link
Here's an example of how to log in a user using Magic Links.
Send a new login Magic Link to user
Call passage.magicLink.login
to send your user a new passcode for logging in. A successful call will return a Magic Link id, which you'll need to finish user login later.
suspend fun sendLoginMagicLink(identifier: String) {
try {
val magicLinkId = passage.magicLink.login(identifier).id
// Returns a Magic Link id which you'll need later to check the status of the magic link.
} catch (e: MagicLinkLoginException) {
when (e){
is MagicLinkInvalidIdentifierLoginException -> {
// Alert user their email or phone number was invalid
}
}
}
}
See the Passage Android Complete example app for full implementation.