如何在 Java 开发过程中正确绕过 reCAPTCHA

问题描述

我在我的 Java 应用程序中使用了 reCAPTCHA,并且有一种类似于以下代码方法

登录请求:

public class LoginRequest {
    @NotEmpty
    private String token;
    
    @NotEmpty
    private String username;
    @NotEmpty
    private String password;
}

登录控制器:




public class LoginController {

    private final Validator validator;

    @Value("${isDevelopment}")
    private boolean isDevelopment;

    public LoginController(Validator validator) {
        this.validator = validator;
    }

    public User login(LoginRequest request) {
        if(isDevelopment || validator.isValid(request.token)) {
            // ...
        }
        throw new InvalidTokenException();
    }
}

在这方法中,我想使用应用程序开发环境变量 isDevelopment 绕过验证。但是,我不确定是否有更优雅的方式。因为 reCAPTCHA 被广泛使用,而且很可能会有更好的标准用于此目的。如何在开发过程中绕过 reCAPTCHA?

更新:这是我的 Validator 课程:

@Component
@requiredArgsConstructor
public class CaptchaValidator {

    private final RecaptchaEnterpriseServiceClient client;

    @Value("${enabled}")
    private boolean isEnabled;

    public boolean isValid(String token) {
      // code omitted
    }
}

解决方法

从技术上讲,这样的设计并没有错——这种方法正在被广泛使用。它被命名为 Feature Flags,并且有 3rd 方软件解决方案可以帮助开发人员处理此类变量(例如 LaunchDarkly)。

从目标编程的角度来看,您也可以通过创建一些包装器接口(比如 UserValidator),将其注入 LoginController...

public class LoginController {
    private final UserValidator validator;

    public LoginController(UserValidator validator) {
        this.validator = validator;
    }

    // ... 

    public User login(LoginRequest request) {
        if(validator.validate(request.token)) { 
            // ...

...使您的 CaptchaValidator 实现这一点,但也为接口创建了一些 dev 存根(比如 AlwaysTrueValidator)。然后在开发过程中,您可以使用您的存根,并在上线时更改配置。您甚至可以利用 Spring profiles

@Configuration
@Profile("production")
public class ProductionConfiguration {
    @Bean
    public LoginController loginController() {
        return new LoginController(new CaptchaValidator());
    }
}

// ...

@Configuration
@Profile("development")
public class DevelopmentConfiguration {
    @Bean
    public LoginController loginController() {
        return new LoginController(new AlwaysTrueValidator());
    }
}