1. Go to this page and download the library: Download shieldlabs/shieldlabs-php library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
shieldlabs / shieldlabs-php example snippets
hieldLabs\Exception\ShieldLabsException;
use ShieldLabs\Exception\ValidationException;
use ShieldLabs\Risk;
use ShieldLabs\ShieldLabs;
function respond(int $status, array $body): never
{
http_response_code($status);
header('Content-Type: application/json');
echo json_encode($body);
exit;
}
// One identification authorizes one action, so remember the request IDs you accepted.
// Marker files keep this snippet self-contained; see "Storing used request IDs" below
// for a database version.
function markRequestIdUsed(string $requestId): bool
{
$marker = sys_get_temp_dir() . '/shieldlabs-used-' . hash('sha256', $requestId);
return @fopen($marker, 'x') !== false; // mode "x" fails when the file already exists
}
// The requestId arrives as a form field or in a JSON body.
$json = json_decode((string) file_get_contents('php://input'), true);
$requestId = $_POST['requestId'] ?? (is_array($json) ? ($json['requestId'] ?? null) : null);
$shieldlabs = new ShieldLabs(['api_key' => 'sec_your_private_key']); // or new ShieldLabs() to read SHIELDLABS_API_KEY
try {
// Polls the History API until the verdict is stored (usually 1-3 seconds after
// the browser call), for up to 10 seconds by default.
$identification = $shieldlabs->identifications->get(is_string($requestId) ? $requestId : '');
} catch (ValidationException) {
respond(400, ['error' => 'requestId must be a UUID']);
} catch (ShieldLabsException) {
respond(503, ['error' => 'verification unavailable']); // unverified is never "clean"
}
$evaluation = Risk::evaluate($identification, [
'is_replay' => fn(string $id): bool => !markRequestIdUsed($id),
]);
if (!$evaluation->ok) {
respond(403, ['error' => 'signup refused', 'reason' => $evaluation->reason?->value]);
}
// Create the account here.
respond(200, ['ok' => true]);
hieldLabs\Event\IdentificationScoredEvent;
use ShieldLabs\Exception\SignatureVerificationException;
use ShieldLabs\Exception\WebhookParseException;
use ShieldLabs\Webhook;
$payload = (string) file_get_contents('php://input'); // the raw body, byte for byte
$signature = $_SERVER['HTTP_X_SHIELD_SIGNATURE'] ?? null;
try {
$event = Webhook::constructEvent($payload, $signature, 'whsec_your_signing_secret'); // or getenv('SHIELDLABS_WEBHOOK_SECRET')
} catch (SignatureVerificationException) {
http_response_code(401); // not signed with this endpoint's secret
exit;
} catch (WebhookParseException) {
http_response_code(400); // signed, but not a webhook event
exit;
}
if ($event instanceof IdentificationScoredEvent) {
$identification = $event->data; // the same Identification model the History API returns
// Store it keyed by $identification->request_id so a repeated delivery is harmless.
}
http_response_code(200); // answer fast: the sender waits at most 1 second
$identification = $shieldlabs->identifications->get($requestId); // wait up to 10 s in total
$identification = $shieldlabs->identifications->get($requestId, ['timeout' => 3]); // a 3-second budget
$identification = $shieldlabs->identifications->get($requestId, ['wait' => false]); // one lookup, no polling
use ShieldLabs\Risk;
use ShieldLabs\RiskBand;
$evaluation = Risk::evaluate($identification, [
'max_age' => 120,
'block_flags' => ['browser_automation', 'javascript_disabled', 'tor'],
'is_replay' => $isReplay,
]);
if (!$evaluation->ok) {
// refuse, and log $evaluation->reason->value
} elseif ($evaluation->band === RiskBand::Suspicious) {
// ask for a second factor
}
// CREATE TABLE used_request_ids (request_id CHAR(36) PRIMARY KEY, used_at TIMESTAMP NOT NULL)
function markRequestIdUsed(PDO $pdo, string $requestId): bool
{
try {
$pdo->prepare('INSERT INTO used_request_ids (request_id, used_at) VALUES (?, CURRENT_TIMESTAMP)')
->execute([$requestId]);
return true;
} catch (PDOException $exception) {
if (str_starts_with((string) $exception->getCode(), '23')) {
return false; // integrity constraint violation: the request ID was used before
}
throw $exception;
}
}
$evaluation = Risk::evaluate($identification, [
'is_replay' => fn(string $id): bool => !markRequestIdUsed($pdo, $id),
]);
use ShieldLabs\LookupType;
$page = $shieldlabs->history->search(LookupType::UserHid, $userHid, ['limit' => 50]);
$page->data; // list of Identification, newest first
$page->total; // rows for this User HID across all pages
// How many accounts has this device been used with?
$accounts = [];
if ($identification->hasDeviceSignals()) {
$rows = $shieldlabs->history->iterate(LookupType::DeviceId, $identification->device_id, ['max_items' => 500]);
foreach ($rows as $row) {
if ($row->user_hid !== null && !in_array($row->user_hid, ['anonymous', 'fail', '-1', 'unknown'], true)) {
$accounts[$row->user_hid] = true;
}
}
}
if (count($accounts) >= 3) {
// send the signup to review
}
use ShieldLabs\UserHid;
$userHid = UserHid::fromUserId((string) $user->id, $userHidSecret);
// Render $userHid into the page and pass it to the browser SDK as the userId.
use ShieldLabs\ShieldLabsManagement;
$management = new ShieldLabsManagement([
'secret_key' => 'your_secret_key', // or SHIELDLABS_SECRET_KEY
'domain' => 'example.com', // or SHIELDLABS_DOMAIN; scheme, path and "www." are removed
]);
$profile = $management->getProfile();
$profile->remaining_identifications; // negative when the account is over its
$shieldlabs = new ShieldLabs([
'api_key' => 'sec_your_private_key',
'http_client' => new GuzzleHttp\Client(['timeout' => 10, 'connect_timeout' => 3]),
]);
// Or always use the built-in client, whatever else is installed:
$shieldlabs = new ShieldLabs([
'api_key' => 'sec_your_private_key',
'http_client' => new ShieldLabs\Http\CurlClient(timeout: 10.0),
]);