Ein CAPTCHA-Token über einen Go-HTTP-Proxy übermitteln

Von solvethree4 Min. Lesezeit

Verwenden Sie für die Zielwebsite einen separaten Go-HTTP-Client, der mit dem von solvethree.SuccessfulProxy ausgewählten Proxy konfiguriert ist. Übermitteln Sie Solution.Token mit der zurückgegebenen Browseridentität. Halten Sie diesen Zieltransport vom solvethree-API-Transport des SDK-Clients getrennt.

Auf dieser Seite

Aufgabe vorbereiten

  1. 1.

    Go-SDK und Zugangsdaten einrichten

    Verwenden Sie das offizielle Modul solvethree.com/sdk in Version v0.1.0 mit Go 1.22 oder neuer. Die Referenz zur Go-Integration enthält Details zur Einrichtung. Setzen Sie SOLVETHREE_API_KEY auf den API-Schlüssel Ihres Workspaces und bewahren Sie ihn auf dem Server auf. Setzen Sie SOLVETHREE_PROXY auf Ihre HTTP- oder HTTPS-Proxy-URL.

  2. 2.

    Website vor dem Lösen konfigurieren

    Der Workspace benötigt ein aktives Profil für den Zielhostnamen. Richten Sie zuerst das Websiteprofil ein; durch Übermitteln eines Hostnamens und einer Aktion wird keines erstellt.

  3. 3.

    Beispielziel ersetzen

    Passen Sie accounts.example.com, die Aktion login und den Anwendungsendpunkt an Ihre Integration an. Site ist ein Hostname, keine vollständige URL. Geben Sie für reCAPTCHA genau eines der Felder Proxy oder ProxyCandidates an; befüllen Sie die Felder Type und URL der Aufgabe nicht. Der standardmäßige reCAPTCHA-Typ ist Enterprise v3.

Über den Proxy übermitteln, der die Aufgabe gelöst hat

Go · Über den erfolgreichen Proxy absenden
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "net/http"
    "net/url"
    "strings"
    "time"
    solvethree "solvethree.com/sdk"
)

func main() {
    client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
    if err != nil { log.Fatal(err) }
    ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
    defer cancel()
    input := solvethree.TaskRequest{Site: "accounts.example.com", Action: "login", Proxy: os.Getenv("SOLVETHREE_PROXY")}
    result, err := client.Solve(ctx, input, solvethree.SolveOptions{})
    if err != nil { log.Fatal(err) }
    fmt.Println("Ready task:", result.ID)

    proxy, ok := solvethree.SuccessfulProxy(input, result)
    if !ok { log.Fatal("No valid successful proxy") }
    proxyURL, err := url.Parse(proxy)
    if err != nil { log.Fatal(err) }
    transport := http.DefaultTransport.(*http.Transport).Clone()
    transport.Proxy = http.ProxyURL(proxyURL)
    defer transport.CloseIdleConnections()
    targetClient := &http.Client{Transport: transport, Timeout: 30*time.Second,
        CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    request, err := http.NewRequestWithContext(ctx, "POST", "https://accounts.example.com/login",
        strings.NewReader(url.Values{"g-recaptcha-response": {result.Solution.Token}}.Encode()))
    if err != nil { log.Fatal(err) }

    request.Header.Set("User-Agent", result.Solution.UserAgent)
    request.Header.Set("sec-ch-ua", result.Solution.SecChUA)
    request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    response, err := targetClient.Do(request)
    if err != nil { log.Fatal(err) }
    defer response.Body.Close()
    fmt.Println("Application HTTP status:", response.StatusCode)
    // Inspect the application response to determine whether submission succeeded.

}

Das SDK löst die Aufgabe, übermittelt aber nichts an die Website. Nach dem Lösen klont das Beispiel http.DefaultTransport und setzt Proxy des Klons über http.ProxyURL. Nur der separate targetClient verwendet diesen Transport; der API-Transport des SDK-Clients bleibt unverändert.

Belassen Sie die Proxy-Zugangsdaten in der Userinfo-Komponente der URL. url.Parse erhält sie für den Proxytransport. Kodieren Sie reservierte Zeichen im Benutzernamen oder Passwort per Prozentkodierung, statt die URL manuell aufzuteilen oder Proxy-Zugangsdaten als Authorization-Header an das Ziel zu senden.

Bewahren Sie die ursprünglichen Aufgabeneingaben auf und verwenden Sie SuccessfulProxy, auch wenn Sie derzeit nur einen Proxy angeben. Bei ProxyCandidates wird der erfolgreiche Kandidat durch Solution.EgressAttempts identifiziert, einen bei eins beginnenden Index in der ursprünglichen Liste. Die Hilfsfunktion erspart das Raten, welcher Kandidat funktioniert hat; beenden Sie den Vorgang, wenn sie false zurückgibt. Kandidatenlisten akzeptieren höchstens zwölf unterschiedliche HTTP- oder HTTPS-Proxy-URLs ohne Pfad, Query oder Fragment.

Header, Formularfelder und Sitzung des Ziels einbeziehen

Das Beispiel verwendet url.Values, um Solution.Token unter g-recaptcha-response formularzukodieren, und setzt den passenden Inhaltstyp. Ersetzen Sie diesen Feldnamen, wenn Ihre Anwendung einen anderen erwartet. Fügen Sie die weiteren erforderlichen Felder des Endpunkts hinzu, etwa Anmeldedaten und einen gegebenenfalls sitzungsgebundenen Anti-CSRF-Wert; ein CAPTCHA-Token ist keine vollständige Anmeldeanfrage.

Verwenden Sie wie im Beispiel die zurückgegebenen Werte UserAgent und SecChUA. Wenn die Lösung auch Einträge in Headers bereitstellt, wenden Sie diese zurückgegebenen Header ebenfalls auf die Zielanfrage an – das Beispiel kopiert diese Sammlung nicht. Halten Sie die Browseridentität konsistent und wählen Sie den passenden Inhaltstyp für den gesendeten Body.

Das Beispiel hat keinen Cookie-Jar. Wenn das Ziel eine Sitzung benötigt, erstellen Sie mit net/http/cookiejar einen Jar, weisen Sie ihn vor Beginn des Ablaufs am Ziel targetClient.Jar zu und verwenden Sie denselben Client für den Seitenabruf und die Formularübermittlung. Verwenden Sie während der gesamten Sitzung denselben erfolgreichen Proxy. Der solvethree-API-Client ist nicht der Sitzungsclient des Ziels.

Prüfen Sie vor dem Zugriff auf die Lösung, ob beim Lösen ein Fehler aufgetreten ist. Nur ein Task im Status ready hat eine nutzbare Lösung; bei einem fehlgeschlagenen Task erklären errorCode und error die Ursache. Behandeln Sie bei der Anfrage an das Ziel zunächst den Fehler von Do und prüfen Sie dann den HTTP-Status, bevor Sie den Antwortinhalt interpretieren. Schließen Sie response.Body immer, wenn Do eine Antwort ohne Fehler zurückgibt, auch bei nicht erfolgreichen HTTP-Antworten.

Das Beispiel deaktiviert automatische Weiterleitungen und gibt den Anwendungsstatus aus. Prüfen Sie den Antwortinhalt und eine gegebenenfalls erwartete Weiterleitung, um festzustellen, ob die Anwendung die Übermittlung akzeptiert hat. Ein Task im Status ready oder ein erfolgreicher HTTP-Status allein belegt das nicht.

Führe deinen ersten Task aus.

Starte mit $5 Workspace-Guthaben.

Workspace erstellen
Ein CAPTCHA-Token über einen Go-HTTP-Proxy übermitteln · solvethree