在 Spring Boot 应用程序中使用 Google reCaptcha

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(231)   2024-04-01 06:20:53

介绍

Google 的 reCaptcha 是一个库,用于防止机器人向您的公共表单提交数据或访问您的公共数据。

在这篇文章中,我们将研究如何将 reCaptcha 与基于 Spring Boot 的 Web 应用程序集成

设置验证码

您应该从管理面板 创建一个 API 密钥。您必须创建一个示例应用程序,如下所示:

发布您应该能够看到密钥和秘密以及一些足以开始使用的说明,如下所示:

创建示例 Spring Boot 应用程序

像往常一样导航到 start.spring.io 并如下所示填写并下载项目:

在您最喜欢的 IDE 中打开,然后运行 RecaptchaDemoApplication 并从 http://localhost:8080 访问应用程序。由于没有定义控制器,您将看到一个错误。

使用表单创建公共页面

我们将利用:

  • 基于 Bootstrap 的主题
  • jQuery
  • jQuery 表单插件
  • jQuery 验证插件
  • 用于通知的 toastr
  • Fontawesome 图标
  • Recaptcha JS

启用 reCaptcha 的表单的 HTML 是:

<form id="signup-form" class="form-horizontal" method="POST" 
      th:action="@{/api/signup}" th:object="${user}">
      <div class="form-group">
        <label class="control-label required">First Name</label>
        <input type="text" th:field="*{firstName}" 
          class="form-control required" />
      </div>
      <div class="form-group">
        <label class="control-label required">Last Name</label>
        <input type="text" th:field="*{lastName}" 
          class="form-control required" />
      </div>
      <div class="form-group">
        <label class="control-label required">Email</label>
        <input type="text" th:field="*{email}" 
          class="form-control required" />
      </div>
      <div class="form-group">
        <label class="control-label required">Password</label>
        <input type="password" th:field="*{password}" 
          class="form-control required" />
      </div>
      <div class="form-group">
        <label class="control-label required">Confirm Password</label>
        <input type="password" th:field="*{confirmPassword}" 
          class="form-control required" />
      </div>
      <div class="g-recaptcha" 
        data-sitekey="6LdGeDcUAAAAALfoMZ2Ltv4EE6AHIYb8nSxhCRh_">
      </div>
      <button type="submit" class="btn btn-primary">Submit</button>
    </form>

上面的重要部分是 divg-recaptcha 类,它具有公共站点密钥。另一个密钥应该在您的服务器中是安全的,您可以使用它来验证来自 Google 服务器的验证码。另外,确保 reCaptcha JS 就在“.

加载 URL http://localhost:8080/ 呈现表单:

创建用于表单处理的 API

接下来是在处理添加用户 API 时验证验证码。 Google 提供了一个端点,我们将向其发布以验证验证码。下面是验证验证码的代码:

@Slf4j
@Service
public class RecaptchaService {

  @Value("${google.recaptcha.secret}") 
  String recaptchaSecret;
  
  private static final String GOOGLE_RECAPTCHA_VERIFY_URL =
    "https://www.google.com/recaptcha/api/siteverify";
  
  @Autowired 
  RestTemplateBuilder restTemplateBuilder;

  public String verifyRecaptcha(String ip, 
    String recaptchaResponse){
    Map<String, String> body = new HashMap<>();
    body.put("secret", recaptchaSecret);
    body.put("response", recaptchaResponse);
    body.put("remoteip", ip);
    log.debug("Request body for recaptcha: {}", body);
    ResponseEntity<Map> recaptchaResponseEntity = 
      restTemplateBuilder.build()
        .postForEntity(GOOGLE_RECAPTCHA_VERIFY_URL+
          "?secret={secret}&response={response}&remoteip={remoteip}", 
          body, Map.class, body);
            
    log.debug("Response from recaptcha: {}", 
      recaptchaResponseEntity);
    Map<String, Object> responseBody = 
      recaptchaResponseEntity.getBody();
      
    boolean recaptchaSucess = (Boolean)responseBody.get("success");
    if ( !recaptchaSucess) {
      List<String> errorCodes = 
        (List)responseBody.get("error-codes");
      
      String errorMessage = errorCodes.stream()
          .map(s -> RecaptchaUtil.RECAPTCHA_ERROR_CODE.get(s))
          .collect(Collectors.joining(", "));
          
      return errorMessage;
    }else {
      return StringUtils.EMPTY;
    }
  }
 }

我们创建了一个映射,将响应代码与 Google 提供的响应消息进行映射,如下所示:

public class RecaptchaUtil {

  public static final Map<String, String> 
    RECAPTCHA_ERROR_CODE = new HashMap<>();

  static {
    RECAPTCHA_ERROR_CODE.put("missing-input-secret", 
        "The secret parameter is missing");
    RECAPTCHA_ERROR_CODE.put("invalid-input-secret", 
        "The secret parameter is invalid or malformed");
    RECAPTCHA_ERROR_CODE.put("missing-input-response", 
        "The response parameter is missing");
    RECAPTCHA_ERROR_CODE.put("invalid-input-response", 
        "The response parameter is invalid or malformed");
    RECAPTCHA_ERROR_CODE.put("bad-request", 
        "The request is invalid or malformed");
  }
}

让我们在表单 api 中使用 RecaptchaService,如下所示:

@PostMapping("/signup")
public ResponseEntity<?> signup(@Valid User user, 
  @RequestParam(name="g-recaptcha-response") String recaptchaResponse,
  HttpServletRequest request
){

  String ip = request.getRemoteAddr();
  String captchaVerifyMessage = 
      captchaService.verifyRecaptcha(ip, recaptchaResponse);

  if ( StringUtils.isNotEmpty(captchaVerifyMessage)) {
    Map<String, Object> response = new HashMap<>();
    response.put("message", captchaVerifyMessage);
    return ResponseEntity.badRequest()
      .body(response);
  }
  userRepository.save(user);
  return ResponseEntity.ok().build();
}

UI 上的验证码作为带有键 g-recaptcha-response 的请求参数在响应中传递。因此,我们使用此响应密钥和选项 ip 地址调用验证码验证服务。验证的结果是成功或失败。如果消息失败,我们将捕获该消息并将其返回给客户端。

此示例的完整代码可在此处 找到。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-using-google-recaptcha-spring-boot-application.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...