Skip to content

SDK de servidor PHP ​

SDK oficial de PHP para el servidor — publicado como captchala/captchala-php en Packagist.

Tres tareas que el SDK gestiona por ti:

  1. Validar — verifica un pass token pt_ del SDK del navegador.
  2. Emitir — genera un server token sct_ de un solo uso para vincular el próximo desafío a una acción / IP / UID concretas.
  3. Moderar — moderación de contenido multimodal (texto + imagen) contra la misma pipeline compatible con OpenAI que utiliza el panel.

Instalación ​

bash
composer require captchala/captchala-php

Requiere PHP ≥ 8.0 con ext-json. Usa cURL si está disponible y recurre a file_get_contents como alternativa.

Validar (token pt_) ​

Pasa la IP del usuario final como tercer argumento (desde CF-Connecting-IP / X-Forwarded-For, con respaldo en REMOTE_ADDR). Es opcional, pero recomendado: se usa para comprobaciones de riesgo adicionales.

php
use Captchala\Client;

$client = new Client('your_app_key', 'your_app_secret');
$result = $client->validate($_POST['captcha_token'], false, captchala_client_ip());

if (!$result->isValid()) {
    http_response_code(400);
    exit($result->getError());   // e.g. "token_expired"
}
// Verification passed; proceed with the request.
// $result->getCaptchaArgs() has platform / user_ip / referer / pkg / solved_at / risk_score

// Real end-user IP behind a CDN / proxy
function captchala_client_ip(): string {
    foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR'] as $h) {
        if (!empty($_SERVER[$h])) {
            $ip = trim(explode(',', $_SERVER[$h])[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
        }
    }
    return '';
}

¿No tienes la IP a mano? Usa $client->validate($_POST['captcha_token']): igual verifica, solo que sin la señal de riesgo adicional basada en la IP.

Si emitiste el server_token original con bind_uid, compara el uid devuelto con el usuario que esperas:

php
if ($result->getUid() !== $expectedUserId) {
    http_response_code(400);
    exit('user mismatch');
}

Emitir un server token ​

Para flujos de alto valor (inicio de sesión, registro, pago) el patrón recomendado es: el backend genera un token sct_ de un solo uso, lo entrega al navegador y este lo pasa como prop serverToken. Cada token es de un solo uso, está acotado a una acción y puede vincularse a IP / UID opcionalmente en el momento de emisión.

php
$issue = $client->issueServerToken(
    action:    'login',
    bindingIp: $request->ip(),
    ttl:       300,         // seconds; default 300
    maxUses:   5,           // SDK retry budget
    bindUid:   $user->id,   // pair with ValidateResult::getUid() on verify
);

if (!$issue->isOk()) {
    return ['error' => $issue->getError()];   // rate_limit_exceeded, invalid_action, ...
}

return ['server_token' => $issue->getToken()];  // hand to browser

Moderar contenido ​

Multimodal — acepta una mezcla de texto y URLs de imagen en formato compatible con OpenAI:

php
$result = $client->moderationCheck([
    ['type' => 'text', 'text' => $userComment],
    ['type' => 'image_url', 'image_url' => ['url' => $uploadedImageUrl]],
], userId: $user->id);

if (!$result->isOk()) {
    // request error: invalid_credentials, no_content, transport failure, ...
    return ['error' => $result->getError()];
}

if ($result->isFlagged()) {
    // upstream model flagged; inspect categories for the why
    if ($result->hasCategory('violence', 'csam')) {
        // hard block
    }
}

Atajo de texto plano:

php
$result = $client->moderationText('user comment here', userId: $user->id);

Las categorías las define el modelo (p. ej. violence, hate, sexual, self-harm); recorre getCategories() de forma defensiva en lugar de codificar un conjunto fijo.

Clases de resultado ​

ClaseMétodos
ValidateResultisValid(), getError(), getUid(), getChallengeId(), getAction(), isOffline(), isClientOnly(), getWarning(), toArray()
IssueResultisOk(), getToken(), getExpiresIn(), getIssuedAt(), getError(), getMessage(), toArray()
ModerationResultisOk(), isFlagged(), hasCategory(...$names), getCategories(), getContentType(), getRaw(), getError(), getMessage(), toArray()

Enlaces ​

MIT-licensed examples · CaptchaLa is operated independently