Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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