Request Only Native Biometrics

Service providers can explicitly request authentication only using native mobile biometrics (if available) by calling authenticateBoundUser() instead of the authenticate() SDK call. This allows providing a more seamless user experience whenever native biometrics are used.

Mobile apps can authenticate using native device biometrics, as opposed to FIDO-based biometrics or fallback methods (if FIDO2 biometrics aren’t supported). In a native flow, the authentication UI comprises only the device prompt for biometrics (e.g., fingerprint) and no other BindID screens (such as email input, login, approval, SMS OTP, etc.). As such, this flow is only available for devices that were registered to BindID using FIDO biometrics and for authentication requests that don’t require any other screens.

The authenticateBoundUser() SDK call allows you to provide a more seamless user experience when performing native mobile biometric authentication. You can control whether or not to display a loader while waiting for the device to prompt for biometrics (default is not to display one). For example, if you request authentication upon mobile app startup, biometrics are prompted immediately after the splash screens. In addition, you can control the timeout of the biometric authentication (default is 10 seconds) – such as in case the user fails to authenticate several times or biometrics aren’t provided.

For both SDK calls, the native flow is used whenever possible. They differ in how they handle the scenario in which native biometrics cannot be used. Whereas authenticate() falls back to a webview flow (e.g., for FIDO-based device registration), authenticateBoundUser() returns an error to the client. Upon receiving an error, you can simply call authenticate() to proceed to a webview flow. Alternatively, you can handle new device registration outside of a login flow using registration links.

Here's an example of invoking the authenticateBoundUser() SDK method, and performing a client-side PKCE token exchange if authentication is successful:

let request = XmBindIdBoundUserAuthenticationRequest(redirectUri: "[REDIRECT_URI]", encrypted: true)
XmBindIdSdk.shared.authenticateBoundUser(bindIdRequestParams: request) { [weak self] response, error in
if let err = error {
if err.code == XmBindIdErrorCode.unknownUser {
//User is not registered. You can call 'XmBindIdSdk.shared.authenticate' API to initiate a BindID registration
} else {
self?.handleError(error: e)
}
} else {
self?.exchange(response: requestResponse)
}
}
func exchange (response: XmBindIdResponse) {
XmBindIdSdk.shared.exchangeToken(exchangeRequest: XmBindIdExchangeTokenRequest.init(codeResponse: response)) { [weak self] (response, error) in
if let e = error {
self?.handleError(error: e)
} else if let tokenResponse = response {
self?.sendTokenToServer(idToken: tokenResponse.idToken, accessToken: tokenResponse.accessToken)
}
}
}
func sendTokenToServer(idToken: String,accessToken: String) {
// Add code to send the ID and access token to your application server here
}
func handleError(error: XmBindIdError) {
// Add code to process the authentication error here
}