如何验证 reCAPTCHA V2 Java (Servlet)
How to validate reCAPTCHA V2 Java (Servlet)
这是一种问答形式 post,我将 post 既是问题又是答案。这样做的主要原因是我花了很多时间寻找最简单的方法来验证 recaptcha V2。因此,我将分享我的知识,以避免开发人员进一步浪费时间。
How to do a server side validation of Google reCAPTCHA V2 or Invisible reCAPTCHA with Java?
我正在为此使用 org.json
库。从 here or read the docs 获取 jar
文件。将 jar 文件添加到您的项目并导入以下 类.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;
使用以下方法进行验证。
/**
* Validates Google reCAPTCHA V2 or Invisible reCAPTCHA.
*
* @param secretKey Secret key (key given for communication between your
* site and Google)
* @param response reCAPTCHA response from client side.
* (g-recaptcha-response)
* @return true if validation successful, false otherwise.
*/
public synchronized boolean isCaptchaValid(String secretKey, String response) {
try {
String url = "https://www.google.com/recaptcha/api/siteverify",
params = "secret=" + secretKey + "&response=" + response;
HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setDoOutput(true);
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
OutputStream out = http.getOutputStream();
out.write(params.getBytes("UTF-8"));
out.flush();
out.close();
InputStream res = http.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(res, "UTF-8"));
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
JSONObject json = new JSONObject(sb.toString());
res.close();
return json.getBoolean("success");
} catch (Exception e) {
//e.printStackTrace();
}
return false;
}
调用上面的方法如下图,
if(isCaptchaValid("enter_your_key_here", request.getParameter("g-recaptcha-response"))){
//valid
}
希望这对您有所帮助。干杯!
编辑:
按照Google, is way more safer, however if you need the GET
method version please refer the edit history.
的推荐使用POST
方法验证信息
不要对 params
变量进行编码。这样做您将始终得到以下响应。
{"error-codes":["missing-input-response","missing-input-secret"],"success":false}
只是为了提供另一种变体:
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.ws.rs.client.*;
import javax.ws.rs.core.*;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.*;
@Component
public class ReCaptcha {
private final WebTarget webTarget;
public ReCaptcha() {
webTarget = ClientBuilder.newClient()
.target("https://www.google.com/recaptcha/api/siteverify")
.queryParam("secret", "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe");
}
public boolean isValid(@NotNull String token) throws IOException {
Response response = this.webTarget.queryParam("response", token)
.request(MediaType.APPLICATION_JSON)
.accept("application/ld+json")
.get();
if (response.getStatus() != 200)
return false;
String stringResponse = response.readEntity(String.class);
JsonNode jsonNode = new ObjectMapper().readTree(stringResponse);
return jsonNode.get("success").asBoolean();
}
}
此外,您可以验证 returned 主机名和操作。
您也可能想要记录 returned 错误代码。
您必须将使用过的 API 密钥替换为您自己的密钥(这是一个测试 API 密钥并且应该始终 return 令牌有效:https://developers.google.com/recaptcha/docs/faq)
将 API 键和 API url 放入额外的 属性 文件中也是一个好主意。
你可以在任何你喜欢的地方注入这个class。
我在特殊例外情况下使用它,而不是 return判断 true 或 false。
这是一种问答形式 post,我将 post 既是问题又是答案。这样做的主要原因是我花了很多时间寻找最简单的方法来验证 recaptcha V2。因此,我将分享我的知识,以避免开发人员进一步浪费时间。
How to do a server side validation of Google reCAPTCHA V2 or Invisible reCAPTCHA with Java?
我正在为此使用 org.json
库。从 here or read the docs 获取 jar
文件。将 jar 文件添加到您的项目并导入以下 类.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;
使用以下方法进行验证。
/**
* Validates Google reCAPTCHA V2 or Invisible reCAPTCHA.
*
* @param secretKey Secret key (key given for communication between your
* site and Google)
* @param response reCAPTCHA response from client side.
* (g-recaptcha-response)
* @return true if validation successful, false otherwise.
*/
public synchronized boolean isCaptchaValid(String secretKey, String response) {
try {
String url = "https://www.google.com/recaptcha/api/siteverify",
params = "secret=" + secretKey + "&response=" + response;
HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
http.setDoOutput(true);
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
OutputStream out = http.getOutputStream();
out.write(params.getBytes("UTF-8"));
out.flush();
out.close();
InputStream res = http.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(res, "UTF-8"));
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
JSONObject json = new JSONObject(sb.toString());
res.close();
return json.getBoolean("success");
} catch (Exception e) {
//e.printStackTrace();
}
return false;
}
调用上面的方法如下图,
if(isCaptchaValid("enter_your_key_here", request.getParameter("g-recaptcha-response"))){
//valid
}
希望这对您有所帮助。干杯!
编辑:
按照Google, is way more safer, however if you need the GET
method version please refer the edit history.
POST
方法验证信息
不要对 params
变量进行编码。这样做您将始终得到以下响应。
{"error-codes":["missing-input-response","missing-input-secret"],"success":false}
只是为了提供另一种变体:
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.ws.rs.client.*;
import javax.ws.rs.core.*;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.*;
@Component
public class ReCaptcha {
private final WebTarget webTarget;
public ReCaptcha() {
webTarget = ClientBuilder.newClient()
.target("https://www.google.com/recaptcha/api/siteverify")
.queryParam("secret", "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe");
}
public boolean isValid(@NotNull String token) throws IOException {
Response response = this.webTarget.queryParam("response", token)
.request(MediaType.APPLICATION_JSON)
.accept("application/ld+json")
.get();
if (response.getStatus() != 200)
return false;
String stringResponse = response.readEntity(String.class);
JsonNode jsonNode = new ObjectMapper().readTree(stringResponse);
return jsonNode.get("success").asBoolean();
}
}
此外,您可以验证 returned 主机名和操作。 您也可能想要记录 returned 错误代码。
您必须将使用过的 API 密钥替换为您自己的密钥(这是一个测试 API 密钥并且应该始终 return 令牌有效:https://developers.google.com/recaptcha/docs/faq) 将 API 键和 API url 放入额外的 属性 文件中也是一个好主意。
你可以在任何你喜欢的地方注入这个class。
我在特殊例外情况下使用它,而不是 return判断 true 或 false。