Implement Custom Authentication with Mobile Apps

MIRACL Trust offers several options for authenticating to your website using a mobile application:

  • QR code
  • deep linking
  • push notification

Typically, the mobile authentication is done via the MIRACL Trust Authenticator app. However, the MIRACL Trust platform lets you integrate its authentication capabilities into your mobile app without having to use the MIRACL Trust Authenticator. To do so, install the MIRACL Trust SDKs and MIRACL Trust JavaScript library and use them to develop your custom authentication.

For information about integrating our mobile SDKs, see Integrate in Mobile Apps and the SDK readmes. For non-native technologies, check our React Native Integration Tutorial, our MIRACL Trust MFA JS Library or contact us at support@miracl.com. If you want to use the MIRACL Trust authentication page, see Integrate through OIDC. If you want to build a custom authentication page, use the information in Integrate in Mobile Apps.

Authenticating with a mobile app calls a method that checks the authentication status. This generates a code that is the same as the code generated if the authentication is done from a browser.

# Authenticate via QR Code

To generate a QR code that will be used for mobile authentication, use this code:

mcl.fetchAccessId("", function (err, session) {
  if (err) {
    return console.error(err);
  }

  // Use your QR library here
  new QRCode(document.getElementById("qrcode"), {
    text: session.qrURL,
    width: 160,
    height: 160,
  });

  poll = function () {
    mcl.fetchStatus(async function (err, data) {
      if (err) {
        console.error(err);
      }

      if (data.status === "authenticated") {
        const params = new URLSearchParams(data.redirectURL.split("?").pop());

        // exchange the authorization code here
        console.log(params.get("code"));

        return;
      }

      if (data.status === "expired") {
        console.info("the authentication session has expired");

        return;
      }

      setTimeout(poll, 2000);
    });
  };

  poll();
});

This returns a QR code URL that is not encoded as a QR code; therefore, you need to use an external library to encode it.

You can display the generated and encoded QR code anywhere on your website.

Scanning the QR code with a mobile device or clicking the link/button opens your mobile application (if already installed); otherwise, it takes the end user to the mobile landing page, where there are links to the Google Play Store and Apple App Store.

To configure the landing page to display links to your application in the app stores:

  1. Go to your project in the MIRACL Trust Portal.
  2. In the Configuration section, go to Mobile Applications.
  3. Type the links to your app in the Google Play Store URL and Apple App Store URL fields.

If the app is installed and SDKs initialised, when the end user scans the QR code and opens the app, the authenticateWithQRCode method is called. It makes a connection to the authentication session created in the browser and then authenticates the user with the M-PIN protocol.

miraclTrust.authenticateWithQRCode(
    user,
    qrCode,
    pinProvider,
    result -> {
        if (result instanceof MIRACLSuccess) {
            // user is authenticated
        } else {
            // user is not authenticated
        }
    }
);
miraclTrust.authenticateWithQRCode(
    user = user,
    qrCode = qrCode,
    pinProvider = pinProvider,
    resultHandler = ResultHandler { result ->
        when (result) {
            is MIRACLSuccess -> {
                // user is authenticated
            }
            is MIRACLError -> {
                // user is not authenticated
            }
        }
    }
)
[[MIRACLTrust getInstance]
    authenticateWithUser:<#Already registered user object#>
                  qrCode:<#QR Code taken from a MIRACL page#>
    didRequestPinHandler:^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)) {
        // Here the user provides their current identity PIN code.

        pinProcessor(<#Provide your pin here#>);
    } completionHandler:^(BOOL isAuthenticated, NSError * _Nullable error) {
        // Handle your authentication result here.
    }];
    MIRACLTrust.getInstance().authenticateWithQRCode(
        user: <#Already registered user object#>,
        qrCode: <#QR Code taken from a MIRACL page#>,
        didRequestPinHandler: { pinProcessor in
            // Here the user provides their current identity PIN code.

            pinProcessor(<#Provide your pin code here#>)
        }, completionHandler: { isAuthenticatedResult, error in
            // Handle your authentication result here.
        }
    )

# Authenticate via Deep Linking

To generate a URL that will be used for mobile authentication via deep linking, use this code:

mcl.fetchAccessId("", function (err, session) {
  if (err) {
    return console.error(err);
  }

  // Use your QR library here
  new QRCode(document.getElementById("qrcode"), {
    text: session.qrURL,
    width: 160,
    height: 160,
  });

  poll = function () {
    mcl.fetchStatus(async function (err, data) {
      if (err) {
        console.error(err);
      }

      if (data.status === "authenticated") {
        const params = new URLSearchParams(data.redirectURL.split("?").pop());

        // exchange the authorization code here
        console.log(params.get("code"));

        return;
      }

      if (data.status === "expired") {
        console.info("the authentication session has expired");

        return;
      }

      setTimeout(poll, 2000);
    });
  };

  poll();
});

This returns a URL that you can display as a link or, preferably, as a button.

Clicking the link/button opens your mobile application (if already installed); otherwise, it takes the end user to the mobile landing page, where there are links to the Google Play Store and Apple App Store.

To configure the landing page to display links to your app in the app stores:

  1. Go to your project in the MIRACL Trust Portal.
  2. In the Configuration section, go to Mobile Applications.
  3. Type the links to your app in the Google Play Store URL and Apple App Store URL fields.

If the app is installed and SDKs initialised, when the end user clicks the link/button and opens the app, the authenticateWithAppLink (or authenticateWithUniversalLinkURL for iOS) method is called. It makes a connection to the authentication session created in the browser and then authenticates the user with the M-PIN protocol.

# Authenticate via Push Notification

Authenticating via push notification is slightly different from the QR code and deep link authentication. To start the push notification flow, the sendPushNotificationForAuth method in our JavaScript library is called. Then, the User ID is passed as a parameter and this sends a notification.

mcl.sendPushNotificationForAuth(email, function callback(err) {
  if (err) {
    if (err.message && err.message.code === "NO_PUSH_TOKEN") {
      console.log(
        "Push authentication request not sent - app not enrolled for user ID",
      );
    }

    return;
  }

  console.log("Push notification sent");
});

As MIRACL Trust uses Firebase Cloud Messaging (FCM) to send notifications, you need to provide your Firebase Service Account Private Key to authorise us to send push notifications to your end users on your behalf. To do so:

  1. Go to your project in the MIRACL Trust Portal.
  2. In the Configuration section, go to Mobile Applications.
  3. Check Enable Push Notification.
  4. Upload your Firebase Service Account Private Key.

It is important to do this as a first step so as to provide an FCM registration token.

When the sendPushNotificationForAuth method is called, it calls an endpoint that checks the User ID for an FCM registration token. If it is not present, an error is returned. If it is present, a request is made to Firebase Cloud Messaging to send a push notification. If Firebase returns an error, we return an error too.

When a push notification is sent successfully, and the end user clicks it, the app opens. The notification’s payload is then passed to the authenticateWithNotificationPayload method in the SDK. It makes a connection to the authentication session created in the browser and authenticates the user with the M-PIN protocol.

Map<String, String> payload = remoteMessage.getData();
miraclTrust.authenticateWithNotificationPayload(
    payload,
    pinProvider,
    result -> {
        if (result instanceof MIRACLSuccess) {
            // user is authenticated
        } else {
            // user is not authenticated
        }
    }
);
val payload = remoteMessage.data
miraclTrust.authenticateWithNotificationPayload(
    payload = payload,
    pinProvider = pinProvider,
    resultHandler = ResultHandler { result ->
        when (result) {
            is MIRACLSuccess -> {
                // user is authenticated
            }
            is MIRACLError -> {
                // user is not authenticated
            }
        }
    }
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    NSDictionary *pushPayload = notification.request.content.userInfo;

    [[MIRACLTrust getInstance]
        authenticateWithPushNotificationPayload:pushPayload
        didRequestPinHandler:^(void (^ _Nonnull pinHandler)(NSString * _Nullable)) {
            // Here the user provides their current identity PIN code.

            pinProcessor(<#Provide your pin here#>);
        } completionHandler:^(BOOL isAuthenticated, NSError * _Nullable error) {
            // Handle your authentication result here.
        }];
}
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let pushPayload = response.notification.request.content.userInfo

    MIRACLTrust
        .getInstance()
        .authenticateWithPushNotificationPayload(
            payload: pushPayload,
            didRequestPinHandler: { pinProcessor in
                // Here the user provides their current identity PIN code.

                pinProcessor(<#Provide your pin code here#>)
            },
            completionHandler: { isAuthenticatedResult, error in
                // Handle your authentication result here.
            }
        )
}