このページでは、reCAPTCHA から送信されるトークンの信頼性をバックエンドで検証するための評価を作成する方法について説明します。 reCAPTCHA は、エンドユーザーがアクションをトリガーすると、暗号化されたレスポンスである reCAPTCHA レスポンス トークン(トークン)を送信します。
生成されたトークンを評価エンドポイントに送信して、バックエンドで execute()
の結果を評価するための評価を作成する必要があります。reCAPTCHA は送信されたトークンを処理し、トークンの有効性とスコアを報告します。
reCAPTCHA の月間評価数のうち、最初の 10,000 回は無料です。毎月の無料使用量上限(1 か月あたり 10,000 回の評価)に達した後も評価の作成を続けるには、Google Cloud プロジェクトに対する課金を有効にする必要があります。reCAPTCHA のお支払い情報については、お支払い情報をご覧ください。
始める前に
- reCAPTCHA 用に環境を準備します。
- reCAPTCHA Enterprise エージェント(
roles/recaptchaenterprise.agent
)の Identity and Access Management ロールがあることを確認します。 - iOS アプリまたはAndroid アプリにスコアベース キーをインストールします。
-
reCAPTCHA に対する認証を設定します。
選択する認証方式は、reCAPTCHA が設定されている環境によって異なります。次の表は、認証を設定するために、適切な認証方法とサポートされているインターフェースを選択する際に有用です。
環境 インターフェース 認証方法 Google Cloud - REST
- クライアント ライブラリ
関連付けられているサービス アカウントを使用します。 オンプレミスまたは別のクラウド プロバイダ REST API キー または Workload Identity 連携を使用します。 API キーを使用する場合は、API キーの制限を適用して API キーを保護することをおすすめします。
クライアント ライブラリ 以下を使用します。
- Python または Java の場合は、API キーまたは Workload Identity 連携を使用します。
API キーを使用する場合は、API キーの制限を適用して API キーを保護することをおすすめします。
- 他の言語の場合は、Workload Identity 連携を使用します。
トークンを取得する
execute()
呼び出しのレスポンスからトークンを取得します。
各ユーザーのトークンには 1 回のみアクセスできます。
ユーザーがモバイルアプリに対して行う後続の操作を評価する必要がある場合、または評価を作成する前にトークンが期限切れになった場合は、execute()
を再度呼び出して新しいトークンを生成する必要があります。
評価の作成
認証を設定したら、reCAPTCHA Enterprise API にリクエストを送信するか、reCAPTCHA クライアント ライブラリを使用して評価を作成します。
検出を向上させるには、評価の作成時に次の追加の値を渡すことをおすすめします。
userAgent
: ユーザー エージェントは、リクエスト ヘッダーの HTTP リクエストに含まれます。詳細については、Mozilla Developer Network のドキュメントでUser-Agent
リクエスト ヘッダーについてをご覧ください。userIpAddress
: バックエンドにリクエストを送信したユーザーの IP アドレスは HTTP リクエストで使用できます。プロキシ サーバーを使用している場合、IP アドレスはX-Forwarded-For
リクエスト ヘッダーで使用できます。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") }
Java
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
次のステップ
- 評価を解釈し、スコアに基づいてモバイルアプリに対して適切な措置を講じる。