PHP code example of shieldlabs / shieldlabs-php

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),
]);

browser --requestId--> your PHP backend --History API--> Identification --> allow / review / refuse
bash
composer