Gin 핸들러에서 Go SDK 사용하기

작성: solvethree읽는 데 3분

공유 solvethree 클라이언트 하나를 사용하고, 제한 시간이 설정된 c.Request.Context()의 하위 컨텍스트를 Solve에 전달하세요. 대상 구성과 API 키는 서버에 보관하고, 작업을 생성하기 전에 애플리케이션 호출자를 인증하세요.

이 페이지의 내용

의존성 설치 및 대상 구성

  1. 1.

    Go 모듈 생성 및 의존성 설치

    현재 Gin 릴리스에는 Go 1.25 이상을 사용하세요. solvethree SDK 자체에는 Go 1.22+가 필요합니다. 자체 모듈 경로를 사용하여 go mod init으로 애플리케이션 모듈을 초기화하세요. 빠른 시작 가이드에 따라 Gin을 설치한 다음, go get으로 solvethree.com/[email protected]을 추가하세요. 공식 SDK는 도메인에서 호스팅되는 공개 모듈 프록시를 통해 제공되며, solvethree.com에서 제공됩니다.

  2. 2.

    서버 자격 증명 설정

    SOLVETHREE_API_KEY를 워크스페이스 API 키로, INTEGRATION_KEY를 내부 애플리케이션이 X-Integration-Key로 전송할 비밀값으로 설정하세요. 두 자격 증명은 별개입니다. 애플리케이션 호출자에게는 solvethree API 키가 필요하지 않습니다.

  3. 3.

    고정 대상 구성

    CAPTCHA_SITE를 대상 호스트명으로, SOLVETHREE_PROXY를 풀이에 사용할 프록시로 설정하세요. 먼저 워크스페이스에 활성 사이트 프로필을 생성하세요. 사이트 프로필 설정을 참고하세요. 예제에서는 Action을 login으로 고정하므로 통합에서 다른 액션을 사용한다면 이 값을 변경하세요. 호스트명과 액션을 설정해도 프로필은 생성되지 않습니다.

인증된 Gin 라우트 추가

클라이언트는 한 번 생성되며 동시 요청에 안전하게 사용할 수 있습니다. 라우트는 solvethree를 호출하기 전에 내부 애플리케이션 자격 증명을 확인합니다. 호출자로부터 요청 ID는 받지만 임의의 대상이나 프록시는 받지 않습니다.

Gin · 공식 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"))
}

작업은 Site, Action, 단일 Proxy를 제공합니다. reCAPTCHA 요구 사항에 따라 Type과 URL은 설정하지 않으며, 기본 Enterprise v3 모드를 사용합니다.

명시적인 컨텍스트 제한 시간은 핸들러의 대기를 180초로 제한하며, 클라이언트 연결이 끊기면 더 일찍 취소될 수 있습니다. HTTP 서버와 모든 리버스 프록시는 이 요청 시간을 허용해야 합니다. 허용할 수 없다면 이 동기식 라우트를 열린 상태로 유지하지 말고 생성과 조회를 별도 작업으로 사용하세요.

리스너는 루프백에 바인딩됩니다. 라우트를 애플리케이션의 기존 내부 인증 및 배포 구성과 통합하세요. 호출자 인증 없이 유료 풀이 엔드포인트를 노출하지 마세요.

비밀 정보 노출 없이 오류 처리

핸들러는 오류 문자열을 비교하는 대신 errors.As를 사용합니다. 최종 실패를 나타내는 TaskFailedError는 작업 ID와 오류 코드가 포함된 502 응답을 생성합니다. 그 외에 래핑된 SDK 오류는 복구용 ID가 포함된 502 응답을 생성합니다. 대체 처리에서는 원시 오류, 자격 증명, 프록시 URL을 노출하지 않고 고정된 400 메시지를 반환합니다.

502 응답이 모두 풀이 실패를 의미하는 것은 아닙니다. errors.Is로 취소와 기한 만료를 구분하세요. HTTP별 처리가 필요하면 errors.As로 중첩된 APIError를 추출해 StatusCode와 RetryAfter를 확인할 수 있습니다. 모든 오류를 새 작업을 생성할 이유로 취급하지 말고, 내부 진단에서 이 차이를 구분하세요.

실패로 종료된 작업은 다시 폴링하지 마세요. 오류 텍스트가 필요하면 해당 작업을 조회한 다음, 원인을 해결한 후 새 풀이를 시작하세요. 실패한 풀이는 환불됩니다.

요청 시간 초과 시 ID 보관

취소는 대기만 중단하며, 원격 작업은 중단하지 않습니다. 예제는 가능한 경우 복구용 ID를 반환하지만 영구 저장하지는 않습니다. 호출자의 연결이 끊기면 해당 JSON 응답이 전달되지 않을 수 있습니다.

  1. 1.

    라우트 호출 전에 요청 ID 할당

    내부 호출자가 각 논리적 풀이에 대해 고정된 X-Request-ID를 유지하도록 하세요. 유효한 ID는 ASCII 영문자, 숫자, 밑줄 또는 하이픈 1–64자로 구성됩니다. ID가 없으면 SDK가 생성하지만, 미리 할당하면 응답이 유실되어도 복구할 수 있습니다.

  2. 2.

    정확한 작업 입력값 보관

    호스트 이름, 액션, 프록시, 요청 ID를 보호된 애플리케이션 저장소에 저장하세요. 환경 설정 변경 후 재시도할 때 작업 입력값이 다른 값으로 조용히 대체되어서는 안 됩니다.

  3. 3.

    새 작업 생성 전에 복구

    작업 ID를 알고 있다면 기한이 설정된 새 컨텍스트로 GetTask를 호출하세요. 작업 ID가 없다면 동일한 요청 ID와 입력값으로 CreateTask를 호출해 원래 작업 요청을 다시 보내세요. 그러면 기존 작업이 반환됩니다. 같은 ID에 다른 입력값을 사용하면 충돌이 발생합니다. 작업이 대기 중이거나 풀이 중일 때만 조회를 계속하세요.

Solve는 작업을 한 번 생성하고, 컨텍스트 기한 내에서 Retry-After를 준수하며 HTTP 상태가 429, 502, 503 또는 504인 일시적인 폴링 응답만 재시도합니다. CreateTask는 POST를 자동으로 재시도하지 않으므로, 생성 요청의 시간이 초과되면 새 요청 ID를 사용하는 대신 복구해야 합니다.

반환된 식별 정보와 함께 토큰 제출

핸들러의 성공 응답에는 권한이 있는 애플리케이션 호출자를 위한 비공개 솔루션 데이터가 포함됩니다. 대상 요청에는 작업 ID가 아닌 Solution.Token을 사용하세요. 반환된 UserAgent와 SecChUA를 사용하고, SuccessfulProxy(originalTask, readyResult)로 성공한 프록시를 가져오세요.

SDK는 대상에 아무것도 제출하지 않습니다. 작업이 준비되었다는 것은 솔루션이 생성되었다는 뜻이지, 웹사이트가 이를 수락했다는 뜻은 아닙니다. 대상의 응답은 별도로 확인하세요.

첫 작업을 실행하세요.

워크스페이스 크레딧 $5로 시작하세요.

워크스페이스 만들기
Gin 핸들러에서 Go SDK 사용하기 · solvethree