Orchestration SDKs

Integrating reCAPTCHA Enterprise into an iOS app

PingOne Advanced Identity Cloud PingAM iOS

To add support for reCAPTCHA Enterprise to your iOS apps, complete the following tasks.

Importing dependencies

You can add the dependencies using Cocoapods or Swift Package Manager (SPM).

Swift Package Manager

  1. With your project open in Xcode, select File > Add Package Dependencies.

  2. In the search bar, enter the ForgeRock SDK for iOS repository URL: https://github.com/ForgeRock/ping-ios-sdk.

  3. Select the ping-ios-sdk package, and then click Add Package.

  4. In the Choose Package Products dialog, set the Add to Target field for the PingReCaptchaEnterprise library to be the name of your project.

  5. Click Add Package.

  6. In your project, import the library:

    // Import the reCAPTCHA Enterprise library
    import PingReCaptchaEnterprise

Cocoapods

  1. If you do not already have CocoaPods, install the latest version.

  2. If you do not already have a Podfile, in a terminal window, run the following command to create a new Podfile:

    pod init
  3. Add the following lines to your Podfile:

    pod 'PingReCaptchaEnterprise', '2.0.0'
  4. Run the following command to install pods:

    pod install

Handling the callback with the SDK

Use code similar to the following to handle the ReCaptchaEnterpriseCallback in your client-side code using the Orchestration SDKs:

import PingJourney
import PingReCaptchaEnterprise

// Process Journey callbacks
node.callbacks.forEach { callback in
    switch callback {
    case let recaptchaCallback as ReCaptchaEnterpriseCallback:
        Task {
            // Execute reCAPTCHA assessment
            let result = await recaptchaCallback.verify()
            switch result {
            case .success:
                // reCAPTCHA assessment successful
                // The token has been automatically set in the callback
                // Continue to the next step in the Journey
                let nextNode = await node.next()
            case .failure(let error):
                // Handle reCAPTCHA-specific errors
                print("reCAPTCHA error: \(error.errorCode) - \(error.errorMessage)")
                // Optionally set a custom error code
                recaptchaCallback.setClientError("recaptcha_failed")
            }
        }

    // Handle other callback types
    default:
        break
    }
}

Configuring the verification

You can pass a number of options into the call to verify() to customize its operation:

Configuring the call to verify() on iOS
import PingJourney
import PingReCaptchaEnterprise

// Process Journey callbacks
node.callbacks.forEach { callback in
    switch callback {
    case let recaptchaCallback as ReCaptchaEnterpriseCallback:
        Task {

            // Execute reCAPTCHA assessment
            let result = await recaptchaCallback.verify { config in
                // Optionally customize the configuration
                config.action = "purchase"
                config.timeout = 20000
                config.logger = LogManager.error
            }

            switch result {
            case .success:
                // reCAPTCHA assessment successful
                // The token has been automatically set in the callback
                // Continue to the next step in the Journey
                let nextNode = await node.next()
            case .failure(let error):
                // Handle reCAPTCHA-specific errors
                print("reCAPTCHA error: \(error.errorCode) - \(error.errorMessage)")
                // Optionally set a custom error code
                recaptchaCallback.setClientError("recaptcha_failed")
            }
        }

    // Handle other callback types
    default:
        break
    }
}

The available properties for configuring the verify() call are as follows:

Property Default Description

siteKey (String)

From server

The reCAPTCHA Enterprise site key is set by the server, and is read-only.

action (String)

ReCaptchaEnterpriseConstants.defaultAction

The type of action you want to verify.

The default ReCaptchaEnterpriseConstants.defaultAction signifies a login action.

You can also specify your own action:

config.action = "password_reset"
config.action = "payment"
config.action = "add_to_cart"

timeout (Double)

15000

How long to wait, in milliseconds, for a verification to complete.

Use longer timeouts for slow networks or critical operations.

payload ([String: Any]?)

nil

Add relevant metadata to help with risk assessment and debugging.

logger (Logger)

LogManager.warning

What level of logging the module should output.

Choose from the following options:

LogManager.debug

Detailed debugging messages, for use during development.

LogManager.error

Only logs errors.

LogManager.info

Logs info-level messages.

LogManager.none

Disables logging.

Customizing the assessment payload

You can add additional data to customize the payload that the server sends to the Google reCAPTCHA Enterprise for assessment.

Add data to the payload to leverage additional functionality provided by reCAPTCHA Enterprise.

The JSON format the payload expects is as follows:

{
  "token": string,
  "siteKey": string,
  "userAgent": string,
  "userIpAddress": string,
  "expectedAction": string,
  "hashedAccountId": string,
  "express": boolean,
  "requestedUri": string,
  "wafTokenAssessment": boolean,
  "ja3": string,
  "headers": [
    string
  ],
  "firewallPolicyEvaluation": boolean,
  "transactionData": {
    object (TransactionData)
  },
  "userInfo": {
    object (UserInfo)
  },
  "fraudPrevention": enum (FraudPrevention)
}

By default, the SDK or the node itself populates the following fields:

  • token

  • siteKey

  • userAgent

  • userIpAddress

  • expectedAction

You can however also override these values if it suits your use case.

You can add custom payload data as part of an authentication journey that includes the reCAPTCHA Enterprise node. Custom data in the journey overrides any custom data added by the client.

To learn more about the payload, refer to Project Assessments - Event in the Google Developer documentation.

To add custom data for an assessment, pass the payload object in the verify configuration:

// Execute reCAPTCHA assessment
let result = await recaptchaCallback.verify { config in
    // Optionally customize the payload
    config.payload = ["firewallPolicyEvaluation": true,
        "transactionData": [
            "transactionId": "TXN-12345",
            "paymentMethod": "CREDIT_CARD",
            "cardBin": "123456",
            "cardLastFour": "1234",
            "currencyCode": "USD",
            "value": 99.99
        ],
        "userInfo": [
            "accountId": "user-abc123",
            "creationMs": "1609459200000"
        ]
    ]
}

Returning custom error codes

You can return a custom error to the node if required for your business logic:

// Optional custom error code
callback.setClientError("custom_client_error")