Skip to content
Open
58 changes: 46 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# friendly-captcha-php

A PHP client for the [Friendly Captcha](https://friendlycaptcha.com) service. This client allows for easy integration and verification of captcha responses with the Friendly Captcha API.
A PHP client for the [Friendly Captcha](https://friendlycaptcha.com) service. This client makes it easy to connect to the Friendly Captcha API for captcha verification or [Risk Intelligence](https://developer.friendlycaptcha.com/docs/v2/risk-intelligence/) retrieval.

> Note, this is for [Friendly Captcha v2](https://developer.friendlycaptcha.com) only.

Expand All @@ -16,7 +16,11 @@ composer require friendlycaptcha/sdk

## Usage

First configure and create a SDK client
Below are some basic examples that demonstrate how to use this SDK.

For complete examples, take a look at the [examples](./examples/) directory.

### Initialization

```php
use FriendlyCaptcha\SDK\{Client, ClientConfig}
Expand All @@ -25,12 +29,12 @@ $config = new ClientConfig();
$config->setAPIKey("<YOUR API KEY>")->setSitekey("<YOUR SITEKEY (optional)>");

// You can also specify which endpoint to use, for example `"global"` or `"eu"`.
// $config->setEndpoint("eu")
// $config->setApiEndpoint("eu")

$captchaClient = new Client($config)
```

Then use it in the endpoint you want to protect
### Verifying a Captcha Response

```php
function handleLoginRequest() {
Expand Down Expand Up @@ -61,6 +65,38 @@ function handleLoginRequest() {
}
```

### Retrieving Risk Intelligence

You can retrieve [Risk Intelligence](https://developer.friendlycaptcha.com/docs/v2/risk-intelligence/) data using a token. This data provides detailed information about the risk profile of a request, including network data, geolocation, browser details, and risk scores.

```php
function getRiskIntelligence() {
global $frcClient;

$token = isset($_POST["frc-risk-intelligence-token"]) ? $_POST["frc-risk-intelligence-token"] : null;
$result = $frcClient->retrieveRiskIntelligence($token);

if ($result->wasAbleToRetrieve()) {
// Risk Intelligence token is valid and data was retrieved successfully.
if ($result->isValid()) {
// Token was invalid or expired.
$response = $result->getResponse();
echo "Risk Intelligence data", $response->data;
} else {
$error = $result->getResponseError();
error_log("Error:", $error);
}
} else {
// Network issue or configuration problem.
if ($result->isClientError()) {
error_log("Configuration error - check your API key");
} else {
error_log("Network issue or service temporarily unavailable");
}
}
}
```

## Development

Make sure you have PHP installed (e.g. with `brew install php` on a Macbook).
Expand Down Expand Up @@ -111,17 +147,15 @@ OK (28 tests, 110 assertions)

### Optional

Install an old version of PHP (to be sure it works in that version). The oldest PHP version this SDK supports is 7.1.

```php
brew install shivammathur/php/php@7.1
echo 'export PATH="/opt/homebrew/opt/php@7.1/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/opt/homebrew/opt/php@7.1/sbin:$PATH"' >> ~/.zshrc
To make sure that the SDK is backwards compatible, make sure the tests pass in PHP 7.1. We recommend using Docker.

# open a new terminal and check the new version
php --version
```console
$ docker run --rm -it --network host -v $PWD:/php -w /php php:7.1-alpine /bin/sh
/php # apk update && apk add git
```

Then follow the steps above starting with [**Install Composer**](#install-composer). You can run `./friendly-captcha-sdk-testserver serve` outside the Docker container.

### Some features you can't use to be compatible with PHP 7.1

- Typings of class member variables.
Expand Down
4 changes: 2 additions & 2 deletions examples/form/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# form

Example of using the Friendly Captcha SDK for PHP.
Example of using the Friendly Captcha SDK for PHP. It displays a form with a captcha and verifies the captcha response on the back-end. If the application has [**Risk Intelligence**](https://developer.friendlycaptcha.com/docs/v2/risk-intelligence/) enabled, it will also generate a token and use it to retrieve the Risk Intelligence data.

## Running the example

Expand All @@ -11,7 +11,7 @@ FRC_APIKEY=YOUR_API_KEY FRC_SITEKEY=YOUR_SITEKEY php -S localhost:8000
Alternatively, you can also specify custom endpoints:

```shell
FRC_SITEKEY=YOUR_API_KEY FRC_APIKEY=YOUR_SITEKEY FRC_SITEVERIFY_ENDPOINT=https://eu-dev.frcapi.com/api/v2/captcha/siteverify FRC_WIDGET_ENDPOINT=https://eu-dev.frcapi.com/api/v2/captcha php -S localhost:8000
FRC_SITEKEY=YOUR_API_KEY FRC_APIKEY=YOUR_SITEKEY FRC_API_ENDPOINT=https://eu-dev.frcapi.com FRC_WIDGET_ENDPOINT=https://eu-dev.frcapi.com php -S localhost:8000
```

Now open your browser and navigate to [http://localhost:8000](http://localhost:8000).
53 changes: 40 additions & 13 deletions examples/form/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
$apikey = getenv('FRC_APIKEY');

// Optionally we can pass in custom endpoints to be used, such as "eu".
$siteverifyEndpoint = getenv('FRC_SITEVERIFY_ENDPOINT');
$apiEndpoint = getenv('FRC_API_ENDPOINT');
$widgetEndpoint = getenv('FRC_WIDGET_ENDPOINT');

const MODULE_SCRIPT_URL = "https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.1.8/site.min.js";
const NOMODULE_SCRIPT_URL = "https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.1.8/site.compat.min.js";; // Compatibility fallback for old browsers.
const MODULE_SCRIPT_URL = "https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.2.0/site.min.js";
const NOMODULE_SCRIPT_URL = "https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.2.0/site.compat.min.js";; // Compatibility fallback for old browsers.

if (empty($sitekey) || empty($apikey)) {
die("Please set the FRC_SITEKEY and FRC_APIKEY environment values before running this example.");
}

function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey)
function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey, string $riskIntelligence)
{
global $widgetEndpoint;
$html = '';
Expand All @@ -31,20 +31,21 @@ function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey)
} else {
$html .= '<p style="color:#ba1f1f">❌ Anti-robot check failed, please try again.<br>See console output for details.</p>';
}
if (!empty($riskIntelligence)) {
$html .= $riskIntelligence;
}
$html .= '<a href=".">Back to form</a>';
}

if (!$didSubmit) {
} else {
$dataEndpoint = empty($widgetEndpoint) ? "" : (' data-api-endpoint="' . $widgetEndpoint . '"');
$html .= '
<form method="POST">
<div class="form-group">
<label>Your Name:</label><br />
<input type="text" name="name" value="Jane Doe"><br />
<label>Message:</label><br />
<textarea name="message"></textarea><br />
<div class="frc-captcha"
data-sitekey="' . $sitekey . '"' .
(isset($widgetEndpoint) ? (' data-api-endpoint="' . $widgetEndpoint . '"') : '') . '></div>
<div class="frc-captcha" data-sitekey="' . $sitekey . '"' . $dataEndpoint . '></div>
<div class="frc-risk-intelligence" data-sitekey="' . $sitekey . '"' . $dataEndpoint . '></div>
<input style="margin-top: 1em" type="submit" value="Submit">
</div>
</form>';
Expand All @@ -55,15 +56,17 @@ function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey)
$config = new \FriendlyCaptcha\SDK\ClientConfig();
$config->setAPIKey($apikey);
$config->setSitekey($sitekey);
if (!empty($siteverifyEndpoint)) {
$config->setSiteverifyEndpoint($siteverifyEndpoint); // Optional, it defaults to "global".
if (!empty($apiEndpoint)) {
$config->setApiEndpoint($apiEndpoint); // Optional, it defaults to "global".
}

$frcClient = new \FriendlyCaptcha\SDK\Client($config);

$didSubmit = $_SERVER['REQUEST_METHOD'] === 'POST';
$captchaOK = false;

$riskIntelligence = "";

if ($didSubmit) {
$captchaResponse = isset($_POST["frc-captcha-response"]) ? $_POST["frc-captcha-response"] : null;
$captchaResult = $frcClient->verifyCaptchaResponse($captchaResponse);
Expand Down Expand Up @@ -91,6 +94,30 @@ function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey)
// In this example we will simply print the message to the console using `error_log`.
error_log("Message submitted by \"" . $name . "\": \"" . $message . "\"");
}

$riskIntelligenceToken = isset($_POST["frc-risk-intelligence-token"]) ? $_POST["frc-risk-intelligence-token"] : null;
$result = $frcClient->retrieveRiskIntelligence($riskIntelligenceToken);
if ($result->wasAbleToRetrieve()) {
if ($result->isValid()) {
$data = $result->getResponse()->data->risk_intelligence;
$riskIntelligence = '
<h3>Risk Intelligence Data</h3>
<dl>
<dt>Location</dt>
<dd>' . $data->network->geolocation->city . ', ' . $data->network->geolocation->country->name . '</dd>
<dt>Device</dt>
<dd><i>Make:</i> ' . $data->client->device->brand . '<br><i>Model:</i> ' . $data->client->device->model . '</dd>
<dt>Overall Risk Score</dt>
<dd>' . $data->risk_scores->overall . '</dd>
</dl>
';
} else {
$error = $result->getResponseError();
error_log("Friendly Captcha API Error:", $error);
}
} else {
error_log("Failed to make the request", $result->errorCode);
}
}
?>

Expand All @@ -112,7 +139,7 @@ function generateForm(bool $didSubmit, bool $captchaOK, string $sitekey)
<body>
<main>
<h1>PHP Form Example</h1>
<?php echo generateForm($didSubmit, $captchaOK, $sitekey); ?>
<?php echo generateForm($didSubmit, $captchaOK, $sitekey, $riskIntelligence); ?>
</main>

<script>
Expand Down
Loading
Loading