Implementing FIDO biometric passwordless authentication using iOS SDK

LoginID
7 min readJan 29, 2021

--

This quickstart guide requires you to use Swift/Objective-C in your development environment.

Steps to follow

  1. Create your client API keys
  2. Install LoginID SDK
  3. Configure LoginID API

Useful APIs

  1. Get User Account Information
  2. Registration
  3. Login
  4. Logout

Create your client API keys

The first step to onboard yourself with LoginID is to create your client credentials. This allows your servers to call LoginID services in an authenticated fashion.

Initial Setup

Install LoginID SDK for your Build Environment

This instruction is for configuring your Xcode environment using Cocoapods (Please refer to https://cocoapods.org/ for more information). The LoginID SDK requires min iOS 10 for compatibility.

This SDK requires biometrics with a secure enclave that is only available on actual devices with iOS 10 +. Simulated devices are not currently supported.

Add Login SDK framework to your Podfile and then run pod install.

platform :ios, '10.0'target 'MyTestObjcApp' douse_frameworks!#LoginSDK pod installpod 'LoginSDK','0.85.36gh', :source => 'https://github.com/loginid1/LoginSDKSpecs.git'# your other podsend

Add NSFaceIDUsageDescription (Privacy — Face ID Usage Description) key/value to app’s info.plist

This is a privacy description for accessing FaceID features on iOS. On devices with FaceID such as iPhoneX+, the user will be prompted with permission dialog based on this description about FaceID usage for the app.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>NSFaceIDUsageDescription</key><string>Privacy description regarding to usage of FaceID feature</string>......</plist>

For Objective-C development, make sure to enable “Embed Swift Standard Libraries” in your build settings to avoid a runtime error for objective-c

Build Settings > Build Options > Always Embed Swift Standard Libraries "YES"

Getting started with LoginID API SDK:

To see an overview of the iOS API SDK, please see:

Getting Started with LoginID API SDK

Import LoginSDK Library

Swift

import LoginSDK

Objective-C

#import "LoginSDK/LoginSDK-Swift.h"

Configure LoginID API

This is the initialization process for our SDK allowing you to inject API keys through the SDK so LoginID can recognize you as a client.

First, you need to configure the SDK with your client API key and baseURL obtained from LoginID’s developer console. This API must call before any other APIs. You should call this API within your AppDelegate’s didFinishLaunchingWithOptions method.

ClientID and baseURL are generated by you on our dashboard when you create an iOS integration. Please refer to:

Initial Setup

Swift

@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// clientId example 032690b3-9bc4-4602-87c1-60c1fae782f2let clientId="<your api key>"// baseURL example https://060ce487-b934-43d0-a925-b66e80c7532f.native-api.auth.loginid.idlet baseURL="<your base url"LoginApi.client.configure(clientId: clientId, baseURL: baseURL)......}......

Objective-C

@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// clientId example 032690b3-9bc4-4602-87c1-60c1fae782f2NSString * clientId=@"<your api key>";// baseURL example 032690b3-9bc4-4602-87c1-60c1fae782f2.https://api.auth.loginid.idNSString * baseURL=@"<your baseURL>";[LoginApi.client configureWithClientId:clientId baseURL:baseURL];......}......

Getting User Account Information

Here is a set of functions for retrieving user information and login status.

Check if the user has an existing registered account:

Swift

// return true or falselet result = LoginApi.client.hasAccount()

Objective-C

// return YES or NOBOOL result = [LoginApi.client hasAccount];

Get the current username:

Swift

// return username in string valuelet username = LoginApi.client.getCurrentUsername()

Objective-C

// return username in string valueNSString * username = [LoginApi.client getCurrentUsername];

Check if the user has an active login session:

Swift

// return true or falselet result = LoginApi.client.isLoggedIn()

Objective-C

// return YES or NOBOOL result = [LoginApi.client isLoggedIn]

Get current access token which is the latest JWT token returned by the server after a successful registered or verified API called:

The returned JWT indicates successful login or registration and can be used to give access to your users for certain activities of your choice, for example, access to a cloud file.

Swift

// return jwt in string valuelet token = LoginApi.client.getCurrentToken()

Objective-C

// return jwt in string valueNSString * token = [LoginApi.client getCurrentToken]

Here is an example of how to use the above functionalities:

Swift

if(LoginApi.client.hasAccount()){// get current username examplelet username = LoginApi.client.getCurrentUsername()// check if user has active login sessionif(LoginApi.client.isLoggedIn()){// get current token examplelet token = LoginApi.client.getCurrentToken()...} else {// can setup login user here//present login option here...}...} else {// user has no account so can setup register user logic here...}

Objective-C

if([LoginApi.client hasAccount]){// get current username exampleNSString * username = [LoginApi.client getCurrentUsername];// check if user has active login sessionif([LoginApi.client isLoggedIn]){// get current token exampleNSString * accessToken = [LoginApi.client getCurrentAccessToken];...} else {// present login option here...}} else {// user has no account so can setup register user logic here...}

Register User Account

For an overview of LoginID registration flow of our API, please see:

Simple Registration Flow

Register an account with username specified

This API allows users to create new credentials with usernames via a FIDO2 registration. Having usernames registered will allow users to login by username from multiple platforms.

Swift

LoginApi.client.register(username: username, onComplete: { (response) inif(response.success){// handle success case here......} else {// handle error case hereprint(response.errorMessage)......}})

Objective-C

[LoginApi.client registerWithUsername:username onComplete:^(RegisterResponse * _Nonnull response) {if(response.success){// handle success case here......} else {// handle error case hereNSLog(response.errorMessage)......}}];

Login or re-authenticate a registered account:

Login or re-authenticate a registered account

Once the user has successfully registered, LoginID will assign a JWT token to the response field. The token has a timestamp associate with it. You can ask the user to re-authenticate at any time afterward based on your business logic or if the token expired.

Swift

LoginApi.client.login(onComplete: { (response) inif(response.success){// handle success case here......} else {// handle error case hereprint(response.errorMessage)......}})

Objective-C

[LoginApi.client loginOnComplete:^(LoginResponse * _Nonnull response) {if(response.success){// handle success case here......} else {// handle error case hereNSLog(response.errorMessage)......}}];

Login with username specified:

This API allows you to signed into a specific account. Use this in a scenario where you want to support multiple registered accounts on the same device.

Swift

// username passed from textfield inputLoginApi.client.login(username:useranme,onComplete: { (response) inif(response.success){// handle success case here......} else {// handle error case hereprint(response.errorMessage)......}})

Objective-C

// username passed from textfield input[LoginApi.client loginWithUsername:username onComplete:^(LoginResponse * _Nonnull response) {if(response.success){// handle success case here......} else {// handle error case hereNSLog(response.errorMessage)......}}];

Transaction Confirmation

Please refer to the transaction confirmation flow for more details:

Transaction Confirmation Flow

Integration Phases

There are 3 phases in integrating the transaction confirmation with LoginID (please refer to above flow for more detail):

  1. Transaction creation: Your platform initializes the transaction to be confirmed and passes the details to LoginID.
  2. Transaction signing: This phase refers to all backend transactions related to getting end users to sign transactions through FIDO. The majority of this phase is done through LoginID itself.
  3. Client verification: This phase refers to the validation activities done by the client to match the signed transactions against the original transaction performed by the end user. Such validation will need to be performed on the client side.

Transaction Signing

Below is a sample code on how to make a transaction confirmation API call as related the phase 2, Transaction signing:

Swift

let payload = TransactionPayload.buildText(nonce: "none value here", data: "transaction text message here")LoginApi.client.transactionConfirmation( payload: payload, viewController: self, onComplete: { (response) inif(response.success){// handle success case here// send response.jwt token value to server for validationprint(response.jwt)} else {// handle failure case hereprint(response.errorMessage)}})

Objective-C

TransactionPayload * payload = [TransactionPayload buildTextWithNonce:@"none value here" data:@"transaction text message here"];[LoginApi.client transactionConfirmationWithPayload:payload viewController:self onComplete:^(TransactionConfirmationResponse * response) {if(response.success){// handle success case here// send response.jwt token value to server for validationNSLog(response.jwt)} else {// handle failure case hereNSLog(response.errorMessage)}}];
  • Nonce: unique ID generated by the client to represent the transaction in string format
  • Transaction Message: Message related to the transaction that will be confirmed by the user’s FIDO operation in string format
  • txCallback: Handler to handle the result of the transaction

Here is the code sample on how to make a transaction confirmation API call when the user is not logged in:

Swift

let payload = TransactionPayload.buildText(nonce: "none value here", data: "transaction text message here")LoginApi.client.transactionConfirmation( username: username, payload: payload, viewController: self, onComplete: { (response) inif(response.success){// handle success case here// send response.jwt token value to server for validationprint(response.jwt)} else {// handle failure case hereprint(response.errorMessage)}})

Objective-C

TransactionPayload * payload = [TransactionPayload buildTextWithNonce:@"none value here" data:@"transaction text message here"];[LoginApi.client transactionConfirmationWithUsername: username payload:payload viewController:self onComplete:^(TransactionConfirmationResponse * response) {if(response.success){// handle success case here// send response.jwt token value to server for validationNSLog(response.jwt)} else {// handle failure case hereNSLog(response.errorMessage)}}];

Client Verification

To verify the transaction, both LoginID and the Client have responsibilities. Once LoginID provides the JWT to the Client, the following steps must be performed by the Client to ensure the JWT, which summarizes the details of the verified transaction, is signed by LoginID. This is a standard JWT verification process, by which the JWT is verified with LoginID’s verification public key.

Please follow the steps outlined on this page to complete the client verification:

Transaction Confirmation — Client Verification

Logout

Call logout operation to invalidate the current access token.

Swift

LoginApi.client.logout()

Objective-C

[LoginApi.client logout];

All your credentials will be revoked once your app is deleted from your device.

Getting help

For any questions, comments or feedback, please contact dev@loginid.io.

About LoginID

LoginID is a comprehensive FIDO-based multifactor authentication solution that offers frictionless authentication. Created with developers and enterprises in mind, LoginID is FIDO-certified and adheres to PSD2 principles. With an implementation time of just one hour, LoginID’s multifactor authentication solution is a quick, simple to integrate, cost-effective, and regulatory friendly tool to give your business peace of mind around security, allowing you to focus on growing your business.

Get started for free.

--

--

LoginID
LoginID

Written by LoginID

LoginID is a comprehensive Passkeys + FIDO-based multi factor authentication solution that offers frictionless biometric authentication at low cost.

No responses yet