How do integrate kaptcha in java spring

人走茶凉 提交于 2019-12-02 12:18:26

You can use reCAPTCHA , follow this tutorial it will help you reCAPTCHA link

  1. Add the maven dependency:

    <dependency>
        <groupId>com.github.penggle</groupId>
        <artifactId>kaptcha</artifactId>
        <version>2.3.2</version>
    </dependency>
    
  2. Add the kaptcha configurations to the application.properties:

    #Kaptcha 
    kaptcha.config.imageWidth=310
    kaptcha.config.imageHeight=55
    kaptcha.config.textProducerCharString=0123456789aAbBcCdDEeFeGgHhIi
    kaptcha.config.textProducerCharLength=6
    kaptcha.config.headerName=KAPTCHA_HEADER
    kaptcha.config.useBorder=no            
    kaptcha.config.textColor=48,101,137
    
  3. Pickup the configurations using @ConfigurationProperties

    @Data
    @Component
    @ConfigurationProperties(prefix="kaptcha.config")
    public class KaptchaConfigurations{
    private String imageWidth;
    private String imageHeight; 
    private String textProducerCharString;
    private String textProducerCharLength;
    private String headerName;
    private String useBorder;
    private String backgroundClass;
    private String textColor;
    }
    

*if you are not using lombok replace @Data with getters and setters.

  1. Declare Producer @Bean:

    @Bean 
    public Producer createKaptchaProducer(KaptchaConfigurations 
    kaptchaConfigurations) {
    DefaultKaptcha kaptcha = new DefaultKaptcha();
    Properties properties = new Properties();
    properties.put(Constants.KAPTCHA_IMAGE_HEIGHT , 
    kaptchaConfigurations.getImageHeight());
    properties.put(Constants.KAPTCHA_IMAGE_WIDTH, 
    kaptchaConfigurations.getImageWidth());
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH , 
    kaptchaConfigurations.getTextProducerCharLength());
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, 
    kaptchaConfigurations.getTextProducerCharString());
    properties.put(Constants.KAPTCHA_BORDER, 
    kaptchaConfigurations.getUseBorder());
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR,
    kaptchaConfigurations.getTextColor());
    properties.put(Constants.KAPTCHA_NOISE_COLOR,
    kaptchaConfigurations.getTextColor());
    kaptcha.setConfig(new Config(properties));
    return kaptcha;
    }
    
  2. Create an endpoint to get the generated captcha and save the captcha text in the session:

    @GetMapping("/image")
    public void handleRequest(
        HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    response.setDateHeader("Expires", 0);       
    response.setHeader("Cache-Control", 
    "no-store, no-cache, must-        revalidate");     
    response.addHeader("Cache-Control", "post-check=0, pre-check=0");       
    response.setHeader("Pragma", "no-cache");       
    response.setContentType("image/jpeg");
    String capText = captchaProducer.createText();
    request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY,     
    capText);
    
    // create the image with the text
    BufferedImage bi = captchaProducer.createImage(capText);
    
    ServletOutputStream out = response.getOutputStream();
    
    // write the data out
    ImageIO.write(bi, "jpg", out);
    try {
        out.flush();
    } finally {
        out.close();
    }
    }
    
  3. Create an aspect to validate the captcha:

    @Aspect
    @Component
    public class KaptchaAspect {
    
        private KaptchaConfigurations kaptchaConfigurations;
    
        public KaptchaAspect(KaptchaConfigurations kaptchaConfigurations) {
            this.kaptchaConfigurations = kaptchaConfigurations;
        }
    
        @Before("@annotation(ValidateKaptcha)")
        public void validateKaptcha() throws Throwable {         
             String headerName = this.kaptchaConfigurations.getHeaderName();
             HttpServletRequest request =
             ((ServletRequestAttributes)                                                     
             RequestContextHolder
             .currentRequestAttributes())
             .getRequest();
             String headerValue = request.getHeader(headerName);
             String kaptchaSessionValue =     
             request.getSession()
            .getAttribute(Constants.KAPTCHA_SESSION_KEY)
            .toString();
    
           if(headerValue == null || kaptchaSessionValue == null) {          
               throw new BusinessException();
           }
    
           if(!headerValue.equals(kaptchaSessionValue)) {           
              throw new BusinessException();
           }
        }
    }
    
  4. Declare the validation annotation:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ValidateKaptcha {
    }
    
  5. Use the @ValidateKaptcha on top of any endpoint needs to validate the captcha:

    @ValidateKaptcha
    @PostMapping("/forgot-password-by-user-name")
    public ResponseEntity<?> forgotPasswordByUsername(@RequestBody @Valid 
           ForgotPasswordByUsernameInput forgotPasswordByUsernameInput) { 
     ...
    }
    

From the client side pass the kaptcha value in the header, name it KAPTCHA_HEADER.

There is an open source Spring Boot starter project witch will validate reCAPTCHA for you.

You just have to set the desired URLs (which you want to protect with captcha, e.g.: /api/sign-up) in your config file and this library will check whether the user sent a valid captcha response.

More on GitHub: https://github.com/Mr-DeWitt/spring-boot-recaptcha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!