Das Go SDK in einem Gin-Handler verwenden

Von solvethree4 Min. Lesezeit

Verwenden Sie einen gemeinsam genutzten solvethree-Client und übergeben Sie einen mit einer Zeitgrenze versehenen untergeordneten Kontext von c.Request.Context() an Solve. Halten Sie die Zielkonfiguration und den API-Schlüssel auf dem Server und authentifizieren Sie den Anwendungsaufrufer, bevor Sie einen Task erstellen.

Auf dieser Seite

Abhängigkeiten installieren und Ziel konfigurieren

  1. 1.

    Go-Modul erstellen und Abhängigkeiten installieren

    Verwenden Sie Go 1.25 oder neuer für die aktuelle Gin-Version. Das solvethree SDK selbst benötigt Go 1.22+. Initialisieren Sie das Modul Ihrer Anwendung mit go mod init und verwenden Sie dabei Ihren eigenen Modulpfad. Installieren Sie Gin anhand der Schnellstartanleitung und fügen Sie anschließend mit go get das Modul solvethree.com/[email protected] hinzu. Das offizielle SDK wird über den öffentlich zugänglichen, auf der Domain gehosteten Modul-Proxy bereitgestellt; es wird von solvethree.com ausgeliefert.

  2. 2.

    Server-Zugangsdaten festlegen

    Setzen Sie SOLVETHREE_API_KEY auf Ihren Workspace-API-Schlüssel und INTEGRATION_KEY auf das Geheimnis, das Ihre interne Anwendung in X-Integration-Key sendet. Dies sind separate Zugangsdaten: Der Anwendungsaufrufer benötigt den solvethree-API-Schlüssel nicht.

  3. 3.

    Festes Ziel konfigurieren

    Setzen Sie CAPTCHA_SITE auf den Zielhostnamen und SOLVETHREE_PROXY auf den für den Lösungsversuch verwendeten Proxy. Erstellen Sie zunächst ein aktives Websiteprofil im Workspace; siehe Einrichtung eines Websiteprofils. Das Beispiel setzt Action fest auf login; ändern Sie diesen Wert, falls Ihre Integration eine andere Aktion verwendet. Das Festlegen von Hostname und Aktion erstellt kein Profil.

Authentifizierte Gin-Route hinzufügen

Der Client wird einmalig erstellt und kann sicher für gleichzeitige Anfragen verwendet werden. Die Route prüft die Zugangsdaten der internen Anwendung, bevor sie solvethree aufruft. Sie akzeptiert eine Anfrage-ID vom Aufrufer, aber kein beliebiges Ziel und keinen beliebigen Proxy.

Gin · Begrenztes Lösen mit dem offiziellen Go-SDK
package main

import (
    "context"
    "errors"
    "log"
    "net/http"
    "os"
    "time"
    "github.com/gin-gonic/gin"
    solvethree "solvethree.com/sdk"
)

func main() {
    client,err:=solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"),nil)
    if err!=nil { log.Fatal(err) }
    secret:=os.Getenv("INTEGRATION_KEY")
    if secret=="" { log.Fatal("Set INTEGRATION_KEY") }
    router:=gin.New()
    router.Use(gin.Recovery())
    router.POST("/captcha/solve",func(c *gin.Context){
        if c.GetHeader("X-Integration-Key")!=secret { c.Status(http.StatusUnauthorized);return }
        input:=solvethree.TaskRequest{Site:os.Getenv("CAPTCHA_SITE"),Action:"login",
            Proxy:os.Getenv("SOLVETHREE_PROXY"),RequestID:c.GetHeader("X-Request-ID")}
        ctx,cancel:=context.WithTimeout(c.Request.Context(),180*time.Second);defer cancel()
        result,err:=client.Solve(ctx,input,solvethree.SolveOptions{})
        if err!=nil {
            var failed *solvethree.TaskFailedError
            var recovery *solvethree.Error
            if errors.As(err,&failed) { c.JSON(502,gin.H{"taskId":failed.TaskID,"errorCode":failed.ErrorCode});return }
            if errors.As(err,&recovery) { c.JSON(502,gin.H{"requestId":recovery.RequestID,"taskId":recovery.TaskID});return }
            c.JSON(400,gin.H{"error":"Invalid task input"});return
        }
        // Return private solution data only to the authorized application caller.
        c.JSON(200,result)
    })
    log.Fatal(router.Run("127.0.0.1:3000"))
}

Der Task übergibt Site, Action und einen einzelnen Proxy. Er lässt Type und URL ungesetzt, wie für reCAPTCHA erforderlich, und verwendet den standardmäßigen Enterprise-v3-Modus.

Die explizite Kontextzeitgrenze begrenzt die Wartezeit des Handlers auf 180 Sekunden; eine Trennung der Clientverbindung kann sie früher beenden. Der HTTP-Server und jeder Reverse-Proxy müssen diese Anfragedauer zulassen. Falls dies nicht möglich ist, verwenden Sie getrennte Vorgänge für Erstellung und Abfrage, statt diese synchrone Route offen zu halten.

Der Listener bindet an die Loopback-Adresse. Integrieren Sie die Route in die bestehende interne Authentifizierung und Bereitstellung Ihrer Anwendung; stellen Sie keinen kostenpflichtigen Lösungsendpunkt ohne Authentifizierung des Aufrufers bereit.

Fehler behandeln, ohne Geheimnisse offenzulegen

Der Handler verwendet errors.As, statt Fehlerstrings abzugleichen. Ein endgültiger TaskFailedError führt zu einer 502-Antwort mit Task-ID und Fehlercode. Andere umschlossene SDK-Fehler führen zu einer 502-Antwort mit Wiederherstellungs-IDs. Der Fallback gibt eine feste 400-Meldung zurück, statt unverarbeitete Fehler, Zugangsdaten oder Proxy-URLs offenzulegen.

Diese 502-Antworten bedeuten nicht alle, dass die Lösung fehlgeschlagen ist. Verwenden Sie errors.Is, um zwischen Abbruch und Fristüberschreitung zu unterscheiden. Für eine HTTP-spezifische Behandlung kann errors.As einen verschachtelten APIError mit StatusCode und RetryAfter extrahieren. Behalten Sie diese Unterscheidung in der internen Diagnose bei, statt jeden Fehler als Anlass zu nehmen, eine weitere Aufgabe zu erstellen.

Eine endgültig fehlgeschlagene Aufgabe sollte nicht erneut abgefragt werden. Rufen Sie sie ab, wenn Sie ihren Fehlertext benötigen, und beheben Sie dann die Ursache, bevor Sie einen weiteren Lösungsvorgang starten. Fehlgeschlagene Lösungsvorgänge werden erstattet.

IDs bei einer Zeitüberschreitung der Anfrage aufbewahren

Ein Abbruch beendet das Warten, nicht die Arbeit auf dem Server. Das Beispiel gibt nach Möglichkeit IDs zur Wiederherstellung zurück, speichert sie aber nicht dauerhaft. Wenn der Aufrufer die Verbindung trennt, kommt diese JSON-Antwort möglicherweise nie an.

  1. 1.

    Anfrage-ID vor dem Aufruf der Route zuweisen

    Lassen Sie den internen Aufrufer für jeden logischen Lösungsvorgang eine stabile X-Request-ID aufbewahren. Gültige IDs enthalten 1–64 ASCII-Buchstaben, Ziffern, Unterstriche oder Bindestriche. Das SDK generiert eine ID, wenn keine vorhanden ist. Wenn Sie sie jedoch vorab zuweisen, ist eine Wiederherstellung auch dann möglich, wenn die Antwort verloren geht.

  2. 2.

    Exakte Aufgabeneingaben aufbewahren

    Speichern Sie Hostname, Aktion, Proxy und Anfrage-ID in einem geschützten Anwendungsspeicher. Bei einem erneuten Versuch nach einer Änderung der Umgebungskonfiguration dürfen nicht stillschweigend andere Aufgabeneingaben verwendet werden.

  3. 3.

    Vor dem Erstellen neuer Arbeit den bestehenden Vorgang wiederherstellen

    Rufen Sie bei bekannter Aufgaben-ID GetTask mit einem neuen zeitlich begrenzten Kontext auf. Ist keine bekannt, senden Sie die ursprüngliche Aufgabe mit derselben Anfrage-ID und denselben Eingaben erneut über CreateTask. Dadurch wird die vorhandene Aufgabe zurückgegeben; andere Eingaben mit derselben ID führen zu einem Konflikt. Setzen Sie den Abruf nur fort, solange die Aufgabe aussteht oder gelöst wird.

Solve erstellt die Aufgabe einmal und wiederholt nur vorübergehend fehlgeschlagene Statusabfragen mit HTTP-Status 429, 502, 503 oder 504. Dabei wird Retry-After innerhalb der Kontextfrist berücksichtigt. CreateTask wiederholt POST niemals automatisch. Eine Zeitüberschreitung beim Erstellen erfordert daher weiterhin eine Wiederherstellung statt einer neuen Anfrage-ID.

Token mit der zurückgegebenen Identität übermitteln

Eine erfolgreiche Handler-Antwort enthält private Lösungsdaten für den autorisierten Anwendungsaufrufer. Verwenden Sie in der Anfrage an das Ziel Solution.Token, nicht die Aufgaben-ID. Verwenden Sie die zurückgegebenen Werte UserAgent und SecChUA und ermitteln Sie den erfolgreichen Proxy mit SuccessfulProxy(originalTask, readyResult).

Das SDK übermittelt nichts an das Ziel. Eine fertige Aufgabe bedeutet, dass eine Lösung generiert wurde, nicht dass die Website sie akzeptiert hat. Prüfen Sie die Antwort des Ziels separat.

Führe deinen ersten Task aus.

Starte mit $5 Workspace-Guthaben.

Workspace erstellen
Das Go SDK in einem Gin-Handler verwenden · solvethree