本页介绍了如何创建评估,以便后端验证 reCAPTCHA 发送的令牌的真实性。 当最终用户触发 HTML 操作时,reCAPTCHA 会发送加密响应,即 reCAPTCHA 响应令牌(也称为令牌)。
对于任何类型的 reCAPTCHA 密钥集成(复选框或得分),您必须通过将生成的令牌提交到评估端点来创建评估,以便评估后端的 execute()
结果。
reCAPTCHA 会处理提交的令牌,并报告令牌的有效性和得分。
reCAPTCHA 每月前 10,000 次评估免费。在达到每月免费用量限额(每月 10,000 次评估)后,如需继续创建评估,您必须为 Google Cloud 项目启用结算功能。如需详细了解 reCAPTCHA 的结算方式,请参阅结算信息。
准备工作
- 为 reCAPTCHA 准备环境。
- 确保您具有以下 Identity and Access Management 角色: reCAPTCHA Enterprise Agent (
roles/recaptchaenterprise.agent
)。 - 在您的网站上安装基于得分的网站密钥或复选框网站密钥。
-
设置 reCAPTCHA 身份验证。
您可以选择的身份验证方法取决于 reCAPTCHA 的设置环境。下表可帮助您选择适当的身份验证方法和支持的接口来设置身份验证:
环境 接口 身份验证方法 Google Cloud - REST
- 客户端库
使用关联的服务账号。 本地或其他云服务提供商 REST 使用 API 密钥或工作负载身份联合。 如果您想使用 API 密钥,我们建议您通过应用 API 密钥限制来保护 API 密钥。
客户端库 使用以下资源:
- 对于 Python 或 Java,请使用 API 密钥或工作负载身份联合。
如果您想使用 API 密钥,我们建议您通过应用 API 密钥限制来保护 API 密钥。
- 对于其他语言,请使用工作负载身份联合。
检索令牌
通过以下任一方式从网页中检索令牌:
- 调用
grecaptcha.enterprise.execute()
返回的 promise 的解析值。 - 用户在您的网站上提交表单时,使用
g-recaptcha-response
POST 参数。 - 作为回调函数的字符串参数(如果在
g-recaptcha
HTML 标记属性中或在grecaptcha.enterprise.render
方法中的回调参数中指定了data-callback
)。
您只能访问每个用户的令牌一次。如果您需要评估用户在您的网站上执行的后续操作,或者在创建评估之前令牌已过期,则必须再次调用 execute()
以生成新的令牌。
创建评估
设置身份验证后,请通过向 reCAPTCHA Enterprise API 发送请求或使用 reCAPTCHA 客户端库来创建评估。
为了提高检测准确性,我们建议您在创建评估时传递以下额外值:
userAgent
:用户代理包含在请求标头中的 HTTP 请求中。如需了解详情,请参阅在 Mozilla 开发者网络文档中了解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 指纹。我们建议您使用 salesforce/ja3 计算 JA3。
- USER_ACTION:您在
grecaptcha.enterprise.execute()
调用中为action
指定的用户发起的操作,例如login
。如需了解详情,请参阅操作名称。
HTTP 方法和网址:
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, "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 响应引入任何其他字段时发生任何中断。
使用 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 指纹。我们建议您使用 salesforce/ja3 计算 JA3。
- USER_ACTION:您在
grecaptcha.enterprise.execute()
调用中为action
指定的用户发起的操作,例如login
。如需了解详情,请参阅操作名称。
HTTP 方法和网址:
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
后续步骤
- 解读评估,并根据得分对您的网站采取适当的措施。