繁体   English   中英

如何验证 reCAPTCHA V2 Java (Servlet)

[英]How to validate reCAPTCHA V2 Java (Servlet)

这是一篇问答风格的帖子,我会同时发布问题和答案。 这样做的主要原因是我花了很多时间寻找验证 recaptcha V2 的最简单方法。 所以我将分享我的知识,以避免开发人员进一步浪费时间。

如何使用Java对 Google reCAPTCHA V2Invisible reCAPTCHA进行服务器端验证

我为此使用org.json库。 这里获取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
}

希望这可以帮助。 干杯!


编辑:使用谷歌推荐的POST方法验证信息更安全,但是如果您需要GET方法版本,请参阅编辑历史记录

不要对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();
    }
}

此外,您可以验证返回的主机名和操作。 此外,您可能希望记录返回的错误代码。

您必须用自己的 API 密钥替换使用过的 API 密钥(这是一个测试 API 密钥,应始终返回令牌有效: https : //developers.google.com/recaptcha/docs/faq )它也可能是一个将 API 密钥和 API url 放入额外的属性文件是个好主意。

你可以在任何你喜欢的地方注入这个类。

我在特殊情况下使用它,而不是返回 true 或 false。

用于网络邮件脚本和评论框:

if(isCaptchaValid("secret", request.getParameter("g-recaptcha-response"))){
  request.setAttribute("Captcha", "true");
try {
  Mailserver.sendEmail(host, port, user, pass, recipient, subject, name, email, content);
  resultMessage = "The e-mail is sent successfully!";
  getServletContext().getRequestDispatcher("/captchacorrect.jsp").forward(request, response);
} catch (Exception ex) {
  ex.printStackTrace();
  resultMessage = "An error occured: " + ex.getMessage();
} finally {
  request.setAttribute("Message", resultMessage);
}
} else {
    getServletContext().getRequestDispatcher("/captchawrong.jsp").forward(request, response);
  } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM