PingOne Recognize

Generating Client State

What is Client State?

The PingOne Recognize client state contains the information needed to restore an account. It can be created during enrollment and authentication.

To create and use a client state, PingOne Recognize requires the user’s biometric to be authenticated.

The temporary state internals are not important, but you can expect a string similar to the following that should be passed as-is to recover the account:

"{\"artifact\":{\"family\":\"davideface_lite\",\"version\":\"1.2.0\",\"target\":\"mobile_sdk\",\"liveness\":\"liveness\"},\"core-client-state\":\"BASE_64_STATE\"}"
When generating client state in your client app using the PingOne Recognize Mobile SDK, a maximum of 50 client states can be generated to keep performance acceptable.

Obtain the Client State

Use the generatingClientState parameter of BiomEnrollConfig or BiomAuthConfig.

For most scenarios, choose BACKUP as the generated client state type.

In Flutter, this parameter is named shouldRetrieveTemporaryState.

Android

During enrollment:

val enrollConfig = BiomEnrollConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.enroll(
  configuration = enrollConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {
        val clientState = result.value.clientState
        // store client state on your backend for future account recovery
      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)

During authentication:

val authConfig = BiomAuthConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.authenticate(
  configuration = authConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {
        val clientState = result.value.clientState
        // store client state on your backend for future account recovery
      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)

iOS

During enrollment:

let enrollConfig = BiomEnrollConfig(generatingClientState: .backup)

Keyless.enroll(
  configuration: enrollConfig,
  onCompletion: { result in
    switch result {
    case .success(let enrollSuccess):
      let clientState = enrollSuccess.clientState
      // store client state on your backend for future account recovery
    case .failure(let error):
      print("error code: \(error.code)")
    }
  }
)

During authentication:

let authConfig = BiomAuthConfig(generatingClientState: .backup)

Keyless.authenticate(
  configuration: authConfig,
  onCompletion: { result in
    switch result {
    case .success(let authSuccess):
      let clientState = authSuccess.clientState
      // store client state on your backend for future account recovery
    case .failure(let error):
      print("error code: \(error.code)")
    }
  }
)

Flutter

During enrollment:

import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';

final enrollConfig = BiomEnrollConfig(shouldRetrieveTemporaryState: true);

try {
  final result = await Keyless.instance.enroll(enrollConfig);
  if (result.temporaryState != null) {
    // store temporary state on your backend for future account recovery
    print("Temporary state retrieved: ${result.temporaryState}");
  }
} catch (error) {
  print("Enrollment failed: $error");
}

During authentication:

import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';

final authConfig = BiomAuthConfig(shouldRetrieveTemporaryState: true);

try {
  final result = await Keyless.instance.authenticate(authConfig);
  if (result.temporaryState != null) {
    // store temporary state on your backend for future account recovery
    print("Temporary state retrieved: ${result.temporaryState}");
  }
} catch (error) {
  print("Authentication failed: $error");
}

React Native

During enrollment:

const config = new BiomEnrollConfig({
  generatingClientState: ClientStateType.BACKUP,
});

const result = await Keyless.enroll(config);
result.fold({
  onSuccess(data) {
    logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
    const clientState = data.clientState;
    // store client state on your backend for future account recovery
    logConsole('Client state ' + JSON.stringify(clientState, null, 2));
  },
  onFailure(error) {
    logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
  },
});

During authentication:

const config = new BiomAuthConfig({
  generatingClientState: ClientStateType.BACKUP,
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Authenticate result success ' + JSON.stringify(data, null, 2));
    const clientState = data.clientState;
    // store client state on your backend for future account recovery
    logConsole('Client state ' + JSON.stringify(clientState, null, 2));
  },
  onFailure(error) {
    logConsole('Authenticate result failure ' + JSON.stringify(error, null, 2));
  },
});