LaravelからCAPTCHA APIを呼び出す

著者:solvethree読了時間:1分

LaravelのHTTPクライアントでsolvethreeタスクを作成し、そのIDでタスクを取得します。APIキーとプロキシ認証情報はサーバー側で保持してください。HTTPレスポンスが成功しただけでは不十分です。解決結果を使用する前にタスクのステータスを確認してください。

このページの内容

サイトとサーバーの認証情報を設定する

  1. 1.

    サイトプロファイルの有効化

    コンソールで対象ホスト名を設定し、ワークスペースに有効なreCAPTCHAプロファイルを用意してください。タスクでホスト名を送信してもプロファイルは作成されません。サイトプロファイルの設定を参照してください。

  2. 2.

    サーバー設定を追加する

    サンプルのsolvethreeエントリをconfig/services.phpの既存の配列に追加します。サーバー環境にSOLVETHREE_API_KEY、CAPTCHA_SITE、SOLVETHREE_PROXYを設定してください。これらの値をブラウザー側のコードに含めないでください。CAPTCHA_SITEは完全なURLではなくホスト名です。

  3. 3.

    対象のアクションに合わせる

    このサンプルはloginを送信します。対象リクエストで使われるアクションに変更してください。proxyを1つ指定するため、proxyCandidatesは併せて送信しないでください。

作成と取得のメソッドを分けたサービスを作成する

Laravelサービス · 認証付きHTTPによる作成と取得
<?php
// app/Services/CaptchaApi.php — configure services.solvethree in config/services.php.
namespace App\Services;

use Illuminate\Support\Facades\Http;
use InvalidArgumentException;

final class CaptchaApi
{
    private function client()
    {
        return Http::baseUrl('https://api.solvethree.com/v1')
            ->withToken(config('services.solvethree.key'))
            ->acceptJson()->asJson()->connectTimeout(10)->timeout(25);
    }

    public function create(string $requestId): array
    {
        if (!preg_match('/^[A-Za-z0-9_-]{1,64}$/', $requestId)) {
            throw new InvalidArgumentException('Invalid logical request ID');
        }
        // The caller keeps this requestId; do not generate another on a timeout.
        return $this->client()->post('/tasks?waitMs=0', [
            'site' => config('services.solvethree.site'),
            'action' => 'login',
            'proxy' => config('services.solvethree.proxy'),
            'requestId' => $requestId,
        ])->throw()->json();
    }

    public function retrieve(string $taskId): array
    {
        if (!preg_match('/^[A-Za-z0-9_-]{1,128}$/', $taskId)) {
            throw new InvalidArgumentException('Invalid task ID');
        }
        return $this->client()->get('/tasks/'.rawurlencode($taskId), ['waitMs' => 15000])
            ->throw()->json();
    }
}
// config/services.php entry:
// 'solvethree' => ['key' => env('SOLVETHREE_API_KEY'),
//   'site' => env('CAPTCHA_SITE'), 'proxy' => env('SOLVETHREE_PROXY')],
// Invoke from your authenticated controller/job. Poll retrieve only while pending
// or solving; ready contains the solution, failed is terminal. Never use retry()
// on create without preserving both this ID and the exact original inputs.

withTokenはワークスペースキーをBearer認証で送信します。POST本文はフラットな構造で、site、action、proxy、requestIdはトップレベルのフィールドです。reCAPTCHAにtypeフィールドやurlフィールドを追加しないでください。recaptchaTypeを省略すると、ドキュメントに記載されたデフォルトのenterprise-v3が選択されます。

どちらのメソッドもjson()の前にthrow()を呼び出します。LaravelのHTTPクライアントは、デフォルトでは成功以外のHTTPレスポンスで例外をスローしません。この呼び出しにより、呼び出し元がHTTPエラーのペイロードを正常なタスクレスポンスとして扱うことを防ぎます。このサービスは接続とリクエストのタイムアウトを設定し、意図的にPOSTの自動再試行を行いません。

タスクIDを保持してステータスを確認する

  1. 1.

    論理的な解決要求ごとに一度だけ作成する

    認証済みのコントローラーまたはジョブでは、createを呼び出す前に、呼び出し元で生成したrequestIdを保持してください。1–64文字のASCII英字、数字、アンダースコア、ハイフンで構成する必要があります。返されたタスクIDは別途保存してください。論理的なリクエストIDは作成の復旧用で、retrieveが受け付けるのはタスクIDです。

  2. 2.

    既存のタスクを取得する

    保存したタスクIDでretrieveを呼び出します。ステータスがpendingまたはsolvingの場合は、コントローラー内で高頻度のループを回すのではなく、後で取得するようにしてください。呼び出し元には待機全体の期限を設けます。サービスのHTTPタイムアウトは個々のリクエストを制限するもので、解決処理の存続期間を制限するものではありません。その期限に達しても、別のタスクを作成する理由にはなりません。

  3. 3.

    最終結果を処理する

    failedの場合は取得を停止し、errorCodeとerrorを確認してください。失敗した解決処理は返金されます。readyの場合は、返された解決トークンを使用します。返されたuserAgentとsecChUaの識別情報、および解決時と同じプロキシを使って送信してください。準備ができた解決結果も、対象に受け入れられる必要があります。

HTTPエラーとタスクの失敗は分けて扱ってください。成功以外のHTTPレスポンスはthrow()で処理されますが、failedを含む成功レスポンスにはタスクレベルの処理が必要です。無効な入力を変更せずに再試行したり、すべての失敗がクレジット不足を意味すると考えたりしないでください。APIエラー処理を参照してください。

別の解決処理を購入せずに、タイムアウトした作成を復旧する

接続タイムアウトだけでは、solvethreeがタスクを作成したかどうかは分かりません。タスクIDがすでにある場合は、そのタスクを取得してください。ない場合は、同じrequestIdと完全に同じタスク入力で作成を再実行し、既存のタスクを復旧します。

最初のタスクを実行しましょう。

$5のワークスペースクレジットで始められます。

ワークスペースを作成
LaravelからCAPTCHA APIを呼び出す · solvethree