Authy Mobile SDK - Getting Started

What is the Authy Mobile SDK

The Authy Mobile SDK for iOS and Android provides a library, code samples and documentation for developers to build mobile applications using Authy OneTouch

Introduction

The following content is a beta build of the Authy Mobile SDK. Currently the SDK only supports OneTouch capabilities (TOTP SoftToken will be in a future release). To fully test drive this SDK, you will need to:

  1. Ensure you have an Authy account with an app created and OneTouch enabled.

  2. Select either the iOS or Android platform.

    1. For Android, you will need Android Studio 2.1+

    2. For iOS you will need Xcode 7.3+ installed.

      1. For Xcode 7.3 you will need OSX 10.11 or above.

      2. If you don't have 10.11, you can download a previous version here. We recommend Xcode 7.2.1

      3. If you have a device with iOS 9 and above you need Xcode 7.3 to be able to run your app

  3. You will need to setup a backend that communicates with Authy in order to register users. You can implement your own backend but we have already created a sample backend that you can use, you can follow our instructions to set it up here

  4. Follow the instructions below for the platform (iOS or Android) of your choice.

Device Registration

Here is the flow for the mobile device registration using the Authy Mobile SDK once you have completed this Getting Started project:

Mobile SDK Flow Diagram

  1. Your mobile app initiates the registration process contacting your backend application.
  2. Your backend application calls the Authy service and starts the device registration process. You will get a registration token to register a new device.
  3. Your backend sends the registration token back to the mobile app to continue the registration process. The Authy service sends a PIN code (SMS or Voice) to the phone number being registered.
  4. Your mobile app registers the device back to the Authy service using the Authy Mobile SDK with the registration token and the PIN code.
  5. Your mobile app calls the sync function in the Authy Mobile SDK to synchronize the device with the Authy service.

Approval Requests

After the registration process is completed, your mobile application will be able to interact with Authy OneTouch approval requests. That way, when a user performs a transaction in the web application you're protecting with 2FA, the process to approve it or deny it shows up on their phone:

Mobile SDK Approval Request

  1. Your backend detects the user has 2FA enabled and triggers a createApprovalRequest to the Authy service. The Authy service will respond with a request ID (uuid).
  2. Your backend application sends a push notification to Apple Push Notification Services (APNS) or Google Cloud Messaging (GCM) to notify the user about the pending approval request with the request ID you received back from the Authy service in the previous step.
  3. Your mobile application receives the push notification.
  4. Your mobile application uses the Authy Mobile SDK to obtain and display the approval request details. Then the Authy Mobile SDK authenticates with the Authy service.
  5. Your user takes an action on an approval request (Approve / Deny) and the mobile app uses the Authy Mobile SDK to send a digitally signed approved/denied request back to the Authy service.
  6. Authy sends a OneTouch callback to your backend application and then you take the appropriate actions based on the results of the operation. Or, your service can poll the Authy OneTouch API asynchronously.

Install the iOS SDK

New Project

  1. Contact Authy sales to download the Authy Mobile SDK files.
  2. Open the AuthySDKSample.xcodeproj file. That will load the project into Apple’s Xcode.

Existing Project

  1. Contact Authy sales to download and extract the AuthyMobileSDKiOS.zip file inside the SDK-Debug or SDK-Release folder. The framework inside the SDK-Debug folder includes x86_64 armv7 arm64 architectures and the one inside SDK-Release contains armv7 arm64 architectures. For testing purposes you should use the framework inside the SDK-Debug folder.

  2. Go to your Xcode project, navigate to the project settings and add the AuthySDKiOS.framework to the Linked Binary with Libraries and to the Embed Frameworks sections under Build Phases like the image below:

Mobile SDK Quickstart Install

Setup Authy in iOS

Initialize an Authy instance. We recommend you to initialize an instance of the Authy SDK using a separate class. We are going to use a class called AuthySDKManager.swift for the rest of these instructions but feel free to use a different name if you want to.

AuthySDKManager.swift

import AuthySDKiOS

class AuthySDKManager: NSObject {

    private var Authy: Authy?

    override init() {
        super.init()
        self.authy = Authy.sharedAuthy

        var setupError: AUTError? = nil
        self.authy?.setup(&setupError)

        if setupError != nil {
            print("Error \(setupError!.message())")
        }
    }
}

You can configure the environment for you app (STG or PROD). By default the environment is set to PROD

AuthySDKManager.swift

var error: AUTError? = nil
self.authy?.setEnvironment(.STG, error: &error)

if error != nil {
    print("Error \(error!.message())")
}

To register the device with the Authy service, call registerDevice, this method should only be called when the user launches the application for the first time.

You need to obtain a registration token before calling the registerDevice method, this is where your backend needs to interact with the Authy backend to register users.

AuthySDKManager.swift

self.authy?.registerDevice(withRegistrationToken: registrationToken, andUniqueDeviceId: uniqueDeviceId, handler: { (error: AUTError?) -> Void in
    // ...
})

To make sure the current device is registered call isDeviceRegistered.

AuthySDKManager.swift

var currentError: AUTError? = nil
let isDeviceRegistered = self.authy?.isDeviceRegistered(&currentError)
if  currentError != nil {
    print("Error \(currentError!.message())")
}

After registering your device, make sure you call the sync method to sync the device every time the app is run. The sync method will synchronize your device with Authy and enable OneTouch capabilities if needed.

AuthySDKManager.swift

self.authy?.sync({ (error: AUTError?) -> Void in
    // ...
})

At this point your app is ready to get a list of approval requests from the Authy backend.

To create a new approval request, you can follow the instructions here or use the pre-built Authy API scripts available here.

Call getApprovalRequests to get the list of approval requests:

AuthySDKManager.swift

var statusOptions: [AUTApprovalRequestStatusOption] = []
let pendingRequests: AUTApprovalRequestStatusOption = AUTApprovalRequestStatusOption(status: .Pending)
statusOptions.append(pendingRequests)

self.authy?.getApprovalRequests(withOptions: statusOptions, completion: { (approvalRequests: [AUTApprovalRequest]?, error: AUTError?) -> Void in
    // ...
})

Once the user has approved or denied the request you will call approveRequest or denyRequest.

If you configured a callback url in the Dasboard to receive notifications when a user approves/denies a request it will be called after this step. Otherwise you should poll the OneTouch API. For more details go here.

Call approveRequest or denyRequest to handle approval requests.

AuthySDKManager.swift

self.authy?.approveRequest(approvalRequest, completion: { (error: AUTError?) -> Void in
    // ...
})

self.authy?.denyRequest(approvalRequest, completion: { (error: AUTError?) -> Void in
    // ...
})

Install the Android SDK

New Project

  1. Contact Authy sales to download the Authy mobile SDK files.
  2. Open Android Studio and load the sample project.
  3. Navigate to the authy-sdk-android folder and open the build.gradle file.

Existing Project

  1. Contact Authy sales to download and extract the AuthyMobileSDKAndroid.zip file.
  2. Go to your Android Studio project and import the com.twilio.authy-sdk-android.aar file. (File -> New -> New Module -> Import .JAR/.AAR package)

Set up Authy in Android

Initialize an Authy instance. We recommend you to initialize an instance of the Authy SDK inside your custom Application class or in your launch screen activity. We are going to use a class called App.java for the rest of these instructions but feel free to use a different name if you want to.

App.java

public class App extends Application {
    private Authy authy;
    @Override
    public void onCreate(){
        super.onCreate();
        authy = Authy.getInstance();
        authy.setup(this);
    }
    public Authy getAuthy(){
        return authy;
    }
}

You can configure the environment for your app (STG or PROD). By default, the environment is set to PROD.

App.java

authy.setEnvironment(Environment.STG);

To register the device with the Authy service, call registerDevice, this method should only be called when the user launches the application for the first time.

You need to obtain a registration token before calling the registerDevice method, this is where your backend needs to interact with the Authy backend to register users. Go here to see how to get your registration token.

The Enable2FAActivity.java class in the Sample App interacts with your backend application (see sample back end, next page) to register the user and calls the registerDevice method:

Enable2FAActivity.java

// You should obtain the registration token from your backend or our sample backend
@Override
public void onRegistrationVerificationSuccess(String registrationToken) {
    // Now register the device
    authy.registerDevice(registrationToken, UUID.randomUUID().toString(),
        new ListenerHelper<Void, DeviceRegistrationListener>(deviceRegistrationListener));
}

// Listener to capture the result from registration
private DeviceRegistrationListener deviceRegistrationListener = new DeviceRegistrationListener() {
    @Override
    public void onSuccess(Void result) {
        // Now sync the device
        authy.sync(new ListenerHelper<Void, SyncListener>(syncListener));
    }
    @Override
    public void onError(Exception exception) {
        Toast.makeText(Enable2FAActivity.this, R.string.registration_error_device, Toast.LENGTH_LONG).show();
        state = RegistrationState.VERIFY;
        updateView();
    }
};

To make sure the current device is registered call isDeviceRegistered. It is useful to check the registration status before starting the registration process. In the sample app this is done on the RegistrationActivity.java class when the user launches the app:

RegistrationActivity.java

authy = ((App) getApplicationContext()).getAuthy();
if (authy.isDeviceRegistered()) {
    startSync();
} else {
    startRegistrationProcess();
}

After registering your device, make sure you sync the device every time the Authy mobile app is started. The sync method will synchronize your device with Authy and enable OneTouch capabilities if needed.

RegistrationActivity.java

private void startSync() {
    displayProgressBar(true);
    authy.sync(new ListenerHelper<Void, SyncListener>(this));
}
@Override
public void onSuccess(Void result) {
    Intent approvalRequestsIntent = new Intent(RegistrationActivity.this, ApprovalRequestsListActivity.class);
    startActivity(approvalRequestsIntent);
    finish();
}
@Override
public void onError(Exception error) {
    if (error instanceof AuthyException) {
        AuthyException exception = (AuthyException) error;
        int exceptionCode = exception.getCode();
        switch (exceptionCode) {
            case AuthyException.NO_CONNECTION:
                Toast.makeText(RegistrationActivity.this, R.string.error_no_connection, Toast.LENGTH_SHORT).show();
                break;
            case AuthyException.DEVICE_SYNC_ERROR:
                Toast.makeText(RegistrationActivity.this, R.string.registration_error_sync, Toast.LENGTH_SHORT).show();
                break;
        }
    }
    finish();
}

At this point your app is ready to get a list of approval requests from the Authy backend.

To create a new approval request, you can follow the instructions here or use the pre-built Authy API scripts available on Github here.

Call getApprovalRequests to get the list of approval requests as in the ApprovalRequestsListActivity.java of the sample app:

ApprovalRequestsListActivity.java

private void fetchApprovalRequests() {
    ApprovalRequestStatusOption statusPending = new ApprovalRequestStatusOption.Builder().build();
    statusPending.setStatus(ApprovalRequest.Status.pending);
    List<ApprovalRequestStatusOption> statusOptions = new ArrayList<>();
    statusOptions.add(statusPending);
    authy.getApprovalRequests(statusOptions, new ListenerHelper<List<ApprovalRequest>, GetApprovalRequestsListener>(this));
}
@Override
public void onSuccess(List<ApprovalRequest> result) {
    approvalRequests = result;
    sectionsPagerAdapter.notifyDataSetChanged();
    bus.post(new ApprovalRequestsUpdatedEvent(true));
}
@Override
public void onError(Exception exception) {
    Log.e(ApprovalRequestsListActivity.class.getSimpleName(), "Error while getting approval requests for device", exception);
    toastHelper.show(ApprovalRequestsListActivity.this, R.string.approval_request_fetch_error);
    bus.post(new ApprovalRequestsUpdatedEvent(true));
}

Once the user has approved or denied the request you will call approve or deny.

If you configured a callback url in the Dasboard to receive notifications when a user approves/denies a request it will be called after this step. Otherwise you should poll the OneTouch API. For more details go here.

The ApprovalRequestDetailActivity.java class in the Sample App shows the details of an approval request and lets the user approve or deny:

ApprovalRequestDetailActivity.java

private void approve() {
    authy.approve(approvalRequest, new ListenerHelper<Void, ApprovalRequestUpdatedListener>(approvalRequestApprovedListener));
}

// Listener to capture the result from approve
private ApprovalRequestUpdatedListener approvalRequestApprovedListener = new ApprovalRequestUpdatedListener() {
    @Override
    public void onSuccess(Void result) {
        toastHelper.show(ApprovalRequestDetailActivity.this, R.string.approve_success);
        finish();
    }
    @Override
    public void onError(Exception exception) {
        toastHelper.show(ApprovalRequestDetailActivity.this, R.string.approve_failed);
        Log.e(ApprovalRequestDetailActivity.class.getSimpleName(), "Exception while denying request", exception);
    }
};
private void deny() {
    authy.deny(approvalRequest, new ListenerHelper<Void, ApprovalRequestUpdatedListener>(approvalRequestDeniedListener));
}

// Listener to capture the result from deny
private ApprovalRequestUpdatedListener approvalRequestDeniedListener = new ApprovalRequestUpdatedListener() {
    @Override
    public void onSuccess(Void result) {
        toastHelper.show(ApprovalRequestDetailActivity.this, R.string.deny_success);
        finish();
    }
    @Override
    public void onError(Exception exception) {
        toastHelper.show(ApprovalRequestDetailActivity.this, R.string.deny_failed);
        Log.e(ApprovalRequestDetailActivity.class.getSimpleName(), "Exception while denying request", exception);
    }
};

What's next

Set Up Sample Backend Application