이 페이지에서는 reCAPTCHA가 전송하는 토큰의 진위성을 백엔드가 확인할 수 있도록 평가를 만드는 방법을 설명합니다. reCAPTCHA는 최종 사용자가 작업을 트리거할 때 암호화된 응답인 reCAPTCHA 응답 토큰(토큰)을 전송합니다.
생성된 토큰을 평가 엔드포인트에 제출하여 백엔드에서 execute()
의 결과를 평가하는 평가를 만들어야 합니다.
reCAPTCHA는 제출된 토큰을 처리하고 토큰의 유효성과 점수를 보고합니다.
reCAPTCHA 월간 평가 첫 10,000회는 무료입니다. 월간 무료 사용량 한도(월간 평가 10,000회)에 도달한 후에도 평가를 계속 만들려면 Google Cloud 프로젝트에 결제를 사용 설정해야 합니다. reCAPTCHA 결제에 대한 자세한 내용은 결제 정보를 참조하세요.
시작하기 전에
- reCAPTCHA 환경을 준비합니다.
- reCAPTCHA 에이전트(
roles/recaptchaenterprise.agent
)라는 Identity and Access Management 역할이 있는지 확인합니다. - iOS 애플리케이션 또는 Android 애플리케이션에 점수 기반 키를 설치합니다.
-
reCAPTCHA에 대한 인증을 설정합니다.
reCAPTCHA가 설정된 환경에 따라 선택하는 인증 방법이 달라집니다. 다음 표는 인증을 설정하는 데 적합한 인증 방법과 지원되는 인터페이스를 선택하는 데 도움이 됩니다.
환경 인터페이스 인증 방법 Google Cloud - REST
- 클라이언트 라이브러리
연결된 서비스 계정을 사용합니다. 온프레미스 또는 다른 클라우드 제공업체 REST API 키 또는워크로드 아이덴티티 제휴를 사용합니다. API 키를 사용하려면 API 키 제한사항을 적용하여 API 키를 보호하는 것이 좋습니다.
클라이언트 라이브러리 다음 중 하나를 사용합니다.
- Python 또는 Java의 경우 API 키 또는 워크로드 아이덴티티 제휴를 사용합니다.
API 키를 사용하려면 API 키 제한사항을 적용하여 API 키를 보호하는 것이 좋습니다.
- 다른 언어의 경우 워크로드 아이덴티티 제휴를 사용하세요.
토큰 검색
execute()
호출의 응답에서 토큰을 검색합니다.
각 사용자의 토큰에 한 번만 액세스할 수 있습니다.
사용자가 모바일 애플리케이션에서 취하는 후속 조치를 평가해야 하는 경우, 또는 평가가 생성되기 전에 토큰이 만료되면 execute()
를 다시 호출하여 새 토큰을 생성해야 합니다.
평가 작성
인증을 설정한 후에는 reCAPTCHA Enterprise API에 요청을 보내거나 reCAPTCHA 클라이언트 라이브러리를 사용하여 평가를 만듭니다.
감지 기능을 개선하려면 평가를 만들 때 다음 값을 추가로 전달하는 것이 좋습니다.
userAgent
: 사용자 에이전트가 요청 헤더의 HTTP 요청에 포함됩니다. 자세한 내용은 Mozilla 개발자 네트워크 문서의User-Agent
요청 헤더에 대해 알아보기를 참조하세요.userIpAddress
: 요청을 백엔드로 전송하는 사용자의 IP 주소를 HTTP 요청에서 사용할 수 있습니다. 프록시 서버를 사용하는 경우X-Forwarded-For
요청 헤더에서 IP 주소를 사용할 수 있습니다. IP 주소를 가져오는 방법에 대한 자세한 내용은X-Forwarded-For
를 참조하세요.ja3
: JA3은 TLS 클라이언트 디지털 지문을 수집할 수 있는 오픈소스 메서드입니다. JA3를 사용하여 TLS 디지털 지문을 만드는 방법에 대한 자세한 내용은 JA3 문서 를 참조하세요.
이를 통해 지능형 공격 패턴과 사람이 주도하는 악용으로부터 웹사이트와 모바일 애플리케이션을 보호할 수 있습니다.
REST API
reCAPTCHA API에 요청을 전송하여 평가를 만듭니다. 인증에 gcloud CLI 또는 API 키를 사용할 수 있습니다.
gcloud CLI 사용
projects.assessments.create
메서드를 사용하여 평가를 작성하세요. 이 요청을 v1
API 엔드포인트로 보냅니다.
요청 데이터를 사용하기 전에 다음을 바꿉니다.
- PROJECT_ID: Google Cloud 프로젝트 ID
- TOKEN:
grecaptcha.enterprise.execute()
호출에서 반환 토큰 - KEY_ID: 사이트 또는 앱과 연결된 reCAPTCHA 키. 자세한 내용은 reCAPTCHA 키를 참조하세요.
- USER_AGENT: 사용자 기기의 요청에 있는 사용자 에이전트입니다.
- USER_IP_ADDRESS: 사용자 기기의 요청에 있는 IP 주소입니다.
- JA3: SSL 클라이언트의 JA3 지문입니다. JA3를 계산할 때는 salesforce/ja3을 사용하는 것이 좋습니다.
- USER_ACTION:
grecaptcha.enterprise.execute()
호출에서action
에 대해 지정한 사용자가 시작한 작업(예:login
)자세한 내용은 작업 이름을 참조하세요.
HTTP 메서드 및 URL:
POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments
JSON 요청 본문:
{ "event": { "token": "TOKEN", "siteKey": "KEY_ID", "userAgent": "USER_AGENT", "userIpAddress": "USER_IP_ADDRESS", "ja3": "JA3", "expectedAction": "USER_ACTION" } }
요청을 보내려면 다음 옵션 중 하나를 선택합니다.
curl
요청 본문을 request.json
파일에 저장하고 다음 명령어를 실행합니다.
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments"
PowerShell
요청 본문을 request.json
파일에 저장하고 다음 명령어를 실행합니다.
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments" | Select-Object -Expand Content
다음과 비슷한 JSON 응답이 표시됩니다.
{ "tokenProperties": { "valid": true, "com.example.app" or "iosBundleId": "com.example.app", "action": "homepage", "createTime": "2019-03-28T12:24:17.894Z" }, "riskAnalysis": { "score": 0.1, "reasons": ["AUTOMATION"] }, "event": { "token": "TOKEN", "siteKey": "KEY_ID", "userAgent": "USER_AGENT", "userIpAddress": "USER_IP_ADDRESS", "ja3": "JA3", "expectedAction": "USER_ACTION" }, "name": "projects/PROJECT_NUMBER/assessments/b6ac310000000000" }
JSON 응답에 도입되는 추가 필드의 경우 중단이 방지되도록 엄격하지 않은 파싱 모드에서 JSON 파서를 사용하는 것이 좋습니다.
API 키 사용
projects.assessments.create
메서드를 사용하여 평가를 작성하세요. 이 요청을 v1
API 엔드포인트로 보냅니다.
요청 데이터를 사용하기 전에 다음을 바꿉니다.
- API_KEY: 현재 프로젝트와 연결된 API 키
- PROJECT_ID: Google Cloud 프로젝트 ID
- TOKEN:
grecaptcha.enterprise.execute()
호출에서 반환 토큰 - KEY_ID: 사이트 또는 앱과 연결된 reCAPTCHA 키. 자세한 내용은 reCAPTCHA 키를 참조하세요.
- USER_AGENT: 사용자 기기의 요청에 있는 사용자 에이전트입니다.
- USER_IP_ADDRESS: 사용자 기기의 요청에 있는 IP 주소입니다.
- JA3: SSL 클라이언트의 JA3 지문입니다. JA3를 계산할 때는 salesforce/ja3을 사용하는 것이 좋습니다.
- USER_ACTION:
grecaptcha.enterprise.execute()
호출에서action
에 대해 지정한 사용자가 시작한 작업(예:login
)자세한 내용은 작업 이름을 참조하세요.
HTTP 메서드 및 URL:
POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments?key=API_KEY
JSON 요청 본문:
{ "event": { "token": "TOKEN", "siteKey": "KEY_ID", "userAgent": "USER_AGENT", "userIpAddress": "USER_IP_ADDRESS", "ja3": "JA3", "expectedAction": "USER_ACTION" } }
요청을 보내려면 다음 옵션 중 하나를 선택합니다.
curl
요청 본문을 request.json
파일에 저장하고 다음 명령어를 실행합니다.
curl -X POST \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments?key=API_KEY"
PowerShell
요청 본문을 request.json
파일에 저장하고 다음 명령어를 실행합니다.
$headers = @{ }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments?key=API_KEY" | Select-Object -Expand Content
다음과 비슷한 JSON 응답이 표시됩니다.
{ "tokenProperties": { "valid": true, "hostname": "www.google.com", "action": "homepage", "createTime": "2019-03-28T12:24:17.894Z" }, "riskAnalysis": { "score": 0.1, "reasons": ["AUTOMATION"] }, "event": { "token": "TOKEN", "siteKey": "KEY_ID", "userAgent": "USER_AGENT", "userIpAddress": "USER_IP_ADDRESS", "ja3": "JA3", "expectedAction": "USER_ACTION" }, "name": "projects/PROJECT_NUMBER/assessments/b6ac310000000000" }
JSON 응답에 도입되는 추가 필드의 경우 중단이 방지되도록 엄격하지 않은 파싱 모드에서 JSON 파서를 사용하는 것이 좋습니다.
C#
using System; using Google.Api.Gax.ResourceNames; using Google.Cloud.RecaptchaEnterprise.V1; public class CreateAssessmentSample { // Create an assessment to analyze the risk of a UI action. // projectID: Google Cloud project ID. // recaptchaKey: reCAPTCHA key obtained by registering a domain or an app to use reCAPTCHA Enterprise. // token: The token obtained from the client on passing the recaptchaKey. // recaptchaAction: Action name corresponding to the token. public void createAssessment(string projectID = "project-id", string recaptchaKey = "recaptcha-key", string token = "action-token", string recaptchaAction = "action-name") { // Create the client. // TODO: To avoid memory issues, move this client generation outside // of this example, and cache it (recommended) or call client.close() // before exiting this method. RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.Create(); ProjectName projectName = new ProjectName(projectID); // Build the assessment request. CreateAssessmentRequest createAssessmentRequest = new CreateAssessmentRequest() { Assessment = new Assessment() { // Set the properties of the event to be tracked. Event = new Event() { SiteKey = recaptchaKey, Token = token, ExpectedAction = recaptchaAction }, }, ParentAsProjectName = projectName }; Assessment response = client.CreateAssessment(createAssessmentRequest); // Check if the token is valid. if (response.TokenProperties.Valid == false) { System.Console.WriteLine("The CreateAssessment call failed because the token was: " + response.TokenProperties.InvalidReason.ToString()); return; } // Check if the expected action was executed. if (response.TokenProperties.Action != recaptchaAction) { System.Console.WriteLine("The action attribute in reCAPTCHA tag is: " + response.TokenProperties.Action.ToString()); System.Console.WriteLine("The action attribute in the reCAPTCHA tag does not " + "match the action you are expecting to score"); return; } // Get the risk score and the reasons. // For more information on interpreting the assessment, // see: https://cloud.google.com/recaptcha/docs/interpret-assessment System.Console.WriteLine("The reCAPTCHA score is: " + ((decimal)response.RiskAnalysis.Score)); foreach (RiskAnalysis.Types.ClassificationReason reason in response.RiskAnalysis.Reasons) { System.Console.WriteLine(reason.ToString()); } } public static void Main(string[] args) { new CreateAssessmentSample().createAssessment(); } }
Go
import ( "context" "fmt" recaptcha "cloud.google.com/go/recaptchaenterprise/v2/apiv1" recaptchapb "cloud.google.com/go/recaptchaenterprise/v2/apiv1/recaptchaenterprisepb" ) func main() { // TODO(developer): Replace these variables before running the sample. projectID := "project-id" recaptchaKey := "recaptcha-key" token := "action-token" recaptchaAction := "action-name" createAssessment(projectID, recaptchaKey, token, recaptchaAction) } /** * Create an assessment to analyze the risk of a UI action. * * @param projectID: Google Cloud project ID * @param recaptchaKey: reCAPTCHA key obtained by registering a domain or an app to use the services of reCAPTCHA Enterprise. * @param token: The token obtained from the client on passing the recaptchaKey. * @param recaptchaAction: Action name corresponding to the token. */ func createAssessment(projectID string, recaptchaKey string, token string, recaptchaAction string) { // Create the recaptcha client. // TODO: To avoid memory issues, move this client generation outside // of this example, and cache it (recommended) or call client.close() // before exiting this method. ctx := context.Background() client, err := recaptcha.NewClient(ctx) if err != nil { fmt.Printf("Error creating reCAPTCHA client\n") } defer client.Close() // Set the properties of the event to be tracked. event := &recaptchapb.Event{ Token: token, SiteKey: recaptchaKey, } assessment := &recaptchapb.Assessment{ Event: event, } // Build the assessment request. request := &recaptchapb.CreateAssessmentRequest{ Assessment: assessment, Parent: fmt.Sprintf("projects/%s", projectID), } response, err := client.CreateAssessment( ctx, request) if err != nil { fmt.Printf("%v", err.Error()) } // Check if the token is valid. if response.TokenProperties.Valid == false { fmt.Printf("The CreateAssessment() call failed because the token"+ " was invalid for the following reasons: %v", response.TokenProperties.InvalidReason) return } // Check if the expected action was executed. if response.TokenProperties.Action == recaptchaAction { // Get the risk score and the reason(s). // For more information on interpreting the assessment, // see: https://cloud.google.com/recaptcha/docs/interpret-assessment fmt.Printf("The reCAPTCHA score for this token is: %v", response.RiskAnalysis.Score) for _,reason := range response.RiskAnalysis.Reasons { fmt.Printf(reason.String()+"\n") } return } fmt.Printf("The action attribute in your reCAPTCHA tag does " + "not match the action you are expecting to score") }
자바
Node.js
const {RecaptchaEnterpriseServiceClient} = require('@google-cloud/recaptcha-enterprise'); /** * Create an assessment to analyze the risk of a UI action. Note that * this example does set error boundaries and returns `null` for * exceptions. * * projectID: Google Cloud project ID * recaptchaKey: reCAPTCHA key obtained by registering a domain or an app to use the services of reCAPTCHA Enterprise. * token: The token obtained from the client on passing the recaptchaKey. * recaptchaAction: Action name corresponding to the token. * userIpAddress: The IP address of the user sending a request to your backend is available in the HTTP request. * userAgent: The user agent is included in the HTTP request in the request header. * ja3: JA3 associated with the request. */ async function createAssessment({ projectID = "your-project-id", recaptchaKey = "your-recaptcha-key", token = "action-token", recaptchaAction = "action-name", userIpAddress = "user-ip-address", userAgent = "user-agent", ja3 = "ja3" }) { // Create the reCAPTCHA client & set the project path. There are multiple // ways to authenticate your client. For more information see: // https://cloud.google.com/docs/authentication // TODO: To avoid memory issues, move this client generation outside // of this example, and cache it (recommended) or call client.close() // before exiting this method. const client = new RecaptchaEnterpriseServiceClient(); const projectPath = client.projectPath(projectID); // Build the assessment request. const request = ({ assessment: { event: { token: token, siteKey: recaptchaKey, userIpAddress: userIpAddress, userAgent: userAgent, ja3: ja3, }, }, parent: projectPath, }); // client.createAssessment() can return a Promise or take a Callback const [ response ] = await client.createAssessment(request); // Check if the token is valid. if (!response.tokenProperties.valid) { console.log("The CreateAssessment call failed because the token was: " + response.tokenProperties.invalidReason); return null; } // Check if the expected action was executed. // The `action` property is set by user client in the // grecaptcha.enterprise.execute() method. if (response.tokenProperties.action === recaptchaAction) { // Get the risk score and the reason(s). // For more information on interpreting the assessment, // see: https://cloud.google.com/recaptcha/docs/interpret-assessment console.log("The reCAPTCHA score is: " + response.riskAnalysis.score); response.riskAnalysis.reasons.forEach((reason) => { console.log(reason); }); return response.riskAnalysis.score; } else { console.log("The action attribute in your reCAPTCHA tag " + "does not match the action you are expecting to score"); return null; } }
PHP
<?php // Include Google Cloud dependencies using Composer // composer require google/cloud-recaptcha-enterprise require 'vendor/autoload.php'; use Google\Cloud\RecaptchaEnterprise\V1\RecaptchaEnterpriseServiceClient; use Google\Cloud\RecaptchaEnterprise\V1\Event; use Google\Cloud\RecaptchaEnterprise\V1\Assessment; use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason; /** * Create an assessment to analyze the risk of a UI action. * @param string $siteKey The key ID for the reCAPTCHA key (See https://cloud.google.com/recaptcha/docs/create-key) * @param string $token The user's response token for which you want to receive a reCAPTCHA score. (See https://cloud.google.com/recaptcha/docs/create-assessment#retrieve_token) * @param string $project Your Google Cloud project ID */ function create_assessment( string $siteKey, string $token, string $project ): void { // TODO: To avoid memory issues, move this client generation outside // of this example, and cache it (recommended) or call client.close() // before exiting this method. $client = new RecaptchaEnterpriseServiceClient(); $projectName = $client->projectName($project); $event = (new Event()) ->setSiteKey($siteKey) ->setToken($token); $assessment = (new Assessment()) ->setEvent($event); try { $response = $client->createAssessment( $projectName, $assessment ); // You can use the score only if the assessment is valid, // In case of failures like re-submitting the same token, getValid() will return false if ($response->getTokenProperties()->getValid() == false) { printf('The CreateAssessment() call failed because the token was invalid for the following reason: '); printf(InvalidReason::name($response->getTokenProperties()->getInvalidReason())); } else { printf('The score for the protection action is:'); printf($response->getRiskAnalysis()->getScore()); // Optional: You can use the following methods to get more data about the token // Action name provided at token generation. // printf($response->getTokenProperties()->getAction() . PHP_EOL); // The timestamp corresponding to the generation of the token. // printf($response->getTokenProperties()->getCreateTime()->getSeconds() . PHP_EOL); // The hostname of the page on which the token was generated. // printf($response->getTokenProperties()->getHostname() . PHP_EOL); } } catch (exception $e) { printf('CreateAssessment() call failed with the following error: '); printf($e); } } // TODO(Developer): Replace the following before running the sample create_assessment( 'YOUR_RECAPTCHA_KEY', 'YOUR_USER_RESPONSE_TOKEN', 'YOUR_GOOGLE_CLOUD_PROJECT_ID' ); ?>
Python
Ruby
다음 단계
- 평가를 해석하고 점수에 따라 모바일 애플리케이션에 적절한 조치 취하기