BlessingCR’s Blog
BlessingCR’s Blog

reCAPTCHA 人机验证 接入

1. 新建gcloud 项目

2. 启用recaptcha api, https://console.cloud.google.com/security/recaptcha?referrer=search&orgonly=true&project=metmake-backend-373703&supportedpurview=organizationId

3. 添加服务账号, 并且添加 captcha 权限

https://blessingcr.com/wp-content/uploads/2023/02/1676970424391.png

4. 生成sitekey,可以在下面网址看到https://console.cloud.google.com/security/recaptcha?hl=zh-cn&project=metmake-backend-373703

/**
* Create reCAPTCHA Site key which binds a domain name to a unique key.
*
* @param projectID : GCloud Project ID.
* @param domainName : Specify the domain name in which the reCAPTCHA should be activated.
*/
public String createSiteKey(String projectID, String domainName) throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the `client.close()` method on the client to safely
// clean up any remaining background resources.
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {

// Set the type of reCAPTCHA to be displayed.
// For different types, see: https://cloud.google.com/recaptcha-enterprise/docs/keys
Key scoreKey =
Key.newBuilder()
.setDisplayName("want.net")
.setWebSettings(
WebKeySettings.newBuilder()
.addAllowedDomains(domainName)
.setAllowAmpTraffic(false)
.setIntegrationType(IntegrationType.SCORE)
.build())
.build();

CreateKeyRequest createKeyRequest =
CreateKeyRequest.newBuilder()
.setParent(ProjectName.of(projectID).toString())
.setKey(scoreKey)
.build();

// Get the name of the created reCAPTCHA site key.
Key response = client.createKey(createKeyRequest);
String keyName = response.getName();
String recaptchaSiteKey = keyName.substring(keyName.lastIndexOf("/") + 1);
System.out.println("reCAPTCHA Site key created successfully. Site Key: " + recaptchaSiteKey);
return recaptchaSiteKey;
}
}

5. 前端使用对应的sitekey 拿到token

<!DOCTYPE html>
<html lang="en">

<head>
<script src="https://www.google.com/recaptcha/enterprise.js?render=6Le8H8kjAAAAANgPHcGsF40zXmorFg4_pm5MHYNu"></script>
</head>
<script src="https://www.google.com/recaptcha/enterprise.js?render=6Le8H8kjAAAAANgPHcGsF40zXmorFg4_pm5MHYNu"></script>
<script>
grecaptcha.enterprise.ready(async () => {
const token = await grecaptcha.enterprise.execute('6LcC9ssjAAAAACN9JhZlt_8AKxdjG6mtEqxbEnka', {action: 'homepage'});
// IMPORTANT: The 'token' that results from execute is an encrypted response sent by
// reCAPTCHA Enterprise to the end user's browser.
// This token must be validated by creating an assessment.
// See https://cloud.google.com/recaptcha-enterprise/docs/create-assessment
console.log(token);
});
</script>

<body>

</body>

</html>

6. 后端通过token, 拿到具体分数

public Boolean allow(String token, String action, Integer type) {
// TODO(developer): Replace these variables before running the sample.
String projectId = googleCloudCaptchaConfig.getProjectId();
String recaptchaSiteKey = null;
if (GoogleCloudCaptchaTypeEnum.SCORE.getType().equals(type)) {
recaptchaSiteKey = googleCloudCaptchaConfig.getScoreKey();
}
if (GoogleCloudCaptchaTypeEnum.CHALLENGE.getType().equals(type)) {
recaptchaSiteKey = googleCloudCaptchaConfig.getChallengeKey();
}
return createAssessment(projectId, recaptchaSiteKey, token, action) >= googleCloudCaptchaConfig.getAllowScore();
}

/**
* Create an assessment to analyze the risk of an UI action. Assessment approach is the same for
* both 'score' and 'checkbox' type recaptcha site keys.
*
* @param projectID : GCloud Project ID
* @param recaptchaSiteKey : Site key obtained by registering a domain/app to use recaptcha
* services. (score/ checkbox type)
* @param token : The token obtained from the client on passing the recaptchaSiteKey.
* @param recaptchaAction : Action name corresponding to the token.
*/
private float createAssessment(String projectID, String recaptchaSiteKey, String token, String recaptchaAction) {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the `client.close()` method on the client to safely
// clean up any remaining background resources.
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
// Set the properties of the event to be tracked.
Event event = Event.newBuilder().setSiteKey(recaptchaSiteKey).setToken(token).build();

// Build the assessment request.
CreateAssessmentRequest createAssessmentRequest =
CreateAssessmentRequest.newBuilder()
.setParent(ProjectName.of(projectID).toString())
.setAssessment(Assessment.newBuilder().setEvent(event).build())
.build();

Assessment response = client.createAssessment(createAssessmentRequest);

// Check if the token is valid.
if (!response.getTokenProperties().getValid()) {
log.info(
"The CreateAssessment call failed because the token was: "
+ response.getTokenProperties().getInvalidReason().name());
return -1f;
}

// Check if the expected action was executed.
// (If the key is checkbox type and 'action' attribute wasn't set, skip this check.)
if (!response.getTokenProperties().getAction().equals(recaptchaAction)) {
log.info(
"The action attribute in reCAPTCHA tag is: "
+ response.getTokenProperties().getAction());
log.info(
"The action attribute in the reCAPTCHA tag "
+ "does not match the action ("
+ recaptchaAction
+ ") you are expecting to score");
return -1f;
}

// Get the reason(s) and the risk score.
// For more information on interpreting the assessment,
// see: https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
for (ClassificationReason reason : response.getRiskAnalysis().getReasonsList()) {
log.info("reason:{}", reason);
}

float recaptchaScore = response.getRiskAnalysis().getScore();
log.info("The reCAPTCHA score is: " + recaptchaScore);

// Get the assessment name (id). Use this to annotate the assessment.
String assessmentName = response.getName();
log.info("Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));
return recaptchaScore;
} catch (IOException e) {
log.error("google cloud captcha err:{}", e.getMessage());
return -2;
}
}

发表回复

textsms
account_circle
email

BlessingCR’s Blog

reCAPTCHA 人机验证 接入
1. 新建gcloud 项目 2. 启用recaptcha api, https://console.cloud.google.com/security/recaptcha?referrer=search&orgonly=true&project=metmake-backend-373703&…
扫描二维码继续阅读
2023-02-21