> Java > java지도 시간 > 본문

SpringBoot+kaptcha로 인증코드를 구현하는 방법

WBOY
풀어 주다: 2023-05-25 14:25:22
앞으로
1595명이 탐색했습니다.

1. 기본 사용법

kaptcha는 아주 오래된 인증 코드 생성 도구입니다. 2006년으로 거슬러 올라갑니다.

오랜 세월이 지났지만 외롭지 않을 뿐만 아니라 여전히 많은 사람들이 사용하고 있어 그 활력을 보여주기에 충분하고 연구할 가치가 있습니다.

편의를 위해 Spring Boot 프로젝트를 생성하여 사용법을 보여줍니다.

먼저 새로운 Spring Boot 프로젝트를 생성하고 다음과 같이 kaptcha의 종속성을 추가합니다.

<dependency>
  <groupId>com.github.penggle</groupId>
  <artifactId>kaptcha</artifactId>
  <version>2.3.2</version>
</dependency>
로그인 후 복사

다음으로 다음과 같이 Kaptcha를 구성하기 위한 Bean만 제공하면 됩니다.

@Configuration
public class KaptchaConfig {
    @Bean(name = "captchaProducer")
    public DefaultKaptcha getKaptchaBean() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有边框 默认为true 我们可以自己设置yes,no
        properties.setProperty(KAPTCHA_BORDER, "yes");
        // 验证码文本字符颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
        // 验证码图片宽度 默认为200
        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
        // 验证码图片高度 默认为50
        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
        // 验证码文本字符大小 默认为40
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
        // KAPTCHA_SESSION_KEY
        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
        // 验证码文本字符长度 默认为5
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}
로그인 후 복사

확인의 각 속성 값을 구성합니다. DefaultKaptcha의 코드 이미지. 각 속성의 의미는 코드에 주석으로 설명되어 있으므로 더 이상 설명하지 않겠습니다.

다음으로 다음과 같이 인터페이스에 인증 코드 이미지를 반환합니다.

@Autowired
DefaultKaptcha defaultKaptcha;
@GetMapping("/img")
public void getKaptcha(HttpServletResponse resp) throws IOException {
    String text = defaultKaptcha.createText();
    BufferedImage image = defaultKaptcha.createImage(text);
    ImageIO.write(image, "jpg", resp.getOutputStream());
}
로그인 후 복사

여기서는 IO 스트림 형식으로 이미지를 프런트 엔드에 씁니다. 물론 Base64 문자열로 변환하여 반환할 수도 있습니다. 프런트 엔드도 마찬가지입니다.

잠깐, 뭔가 빠진 것 같아요!

생성된 인증코드 텍스트를 세션에 저장하지 않아 로그인 시 인증이 불가능합니다. 몇몇 친구들은 '이거 간단하지 않냐?'라고 말할 수도 있습니다. 그냥 인터페이스에 저장하는 것만으로는 충분하지 않나요?

노노노노!

DefaultKaptcha 빈을 구성할 때 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); 코드 줄이 있습니다. 이 코드 줄은 생성된 확인이 자동으로 수행된다는 것을 의미합니다. 텍스트는 세션에 저장되며 세션의 KEY는 kaptchaCode입니다. 그러나 실제 테스트를 해보면 위의 코드는 인증코드에 의해 생성된 텍스트를 세션에 저장하지 않는다는 것을 알 수 있습니다. properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");,这行代码的意思就是说会自动将生成的验证码文本存入到 session 中,并且 session 的 KEY 是 kaptchaCode。但是在实际测试中,大家会发现上面的代码并不会将验证码生成的文本存入到 session 中。

原因在于 Kaptcha 工具实际上自己提供了一个生成验证码图片的 Servlet,如果我们直接使用它自己提供的验证码 Servlet,那么上面这个配置才会生效,在 Spring Boot 中,如果想要配置 Kaptcha 自己提供的 Servlet,方式如下:

@Bean
ServletRegistrationBean<HttpServlet> kaptchaServlet() {
    ServletRegistrationBean<HttpServlet> bean = new ServletRegistrationBean<>();
    bean.setServlet(new KaptchaServlet());
    bean.addUrlMappings("/img");
    Properties properties = new Properties();
    // 是否有边框 默认为true 我们可以自己设置yes,no
    properties.setProperty(KAPTCHA_BORDER, "yes");
    // 验证码文本字符颜色 默认为Color.BLACK
    properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
    // 验证码图片宽度 默认为200
    properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
    // 验证码图片高度 默认为50
    properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
    // 验证码文本字符大小 默认为40
    properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
    // KAPTCHA_SESSION_KEY
    properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
    // 验证码文本字符长度 默认为5
    properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
    // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
    properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
    // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
    properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
    Map<String, String> map = new HashMap<String,String>((Map)properties);
    bean.setInitParameters(map);
    return bean;
}
로그인 후 복사

项目启动后,直接访问 /img 就能看到验证码图片,此时验证码的文本也会自动存入到 session 中。当用户登录的时候,通过 session.getAttribute("kaptchaCode") 就可以获取到验证码的文本内容。

然而很多时候,验证码接口返回的内容都是比较丰富的,可能不仅仅是图片,还有其他信息。所以我们直接配一个 Servlet 并不能满足我们的要求,只能自己写验证码的接口,自己写的话,就要自己把验证码图片存到 session 中去,那么 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); 配置其实就没用了,可以不用加。

2. 自定义验证码文本

当然,我们也可以自定义验证码文本,只需要提供一个验证码文本的实现类即可,如下:

public class KaptchaTextCreator extends DefaultTextCreator {
    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");

    @Override
    public String getText() {
        Integer result = 0;
        Random random = new Random();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomoperands = (int) Math.round(Math.random() * 2);
        if (randomoperands == 0) {
            result = x * y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("*");
            suChinese.append(CNUMBERS[y]);
        } else if (randomoperands == 1) {
            if (!(x == 0) && y % x == 0) {
                result = y / x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("/");
                suChinese.append(CNUMBERS[x]);
            } else {
                result = x + y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("+");
                suChinese.append(CNUMBERS[y]);
            }
        } else if (randomoperands == 2) {
            if (x >= y) {
                result = x - y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[y]);
            } else {
                result = y - x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[x]);
            }
        } else {
            result = x + y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("+");
            suChinese.append(CNUMBERS[y]);
        }
        suChinese.append("=?@" + result);
        return suChinese.toString();
    }
}
로그인 후 복사

这段代码并不难理解,生成的验证码文本类似于 1+1=?@2

그 이유는 Kaptcha 도구가 실제로 인증 코드 이미지를 생성하는 서블릿을 제공하기 때문입니다. Kaptcha 자체를 구성하려는 경우 Spring Boot에서 위의 구성이 적용됩니다. 제공되는 서블릿은 다음과 같습니다.

properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "org.javaboy.tienchin.framework.config.KaptchaTextCreator");
로그인 후 복사
프로젝트 시작 후 /img에 직접 접속하시면 인증코드 이미지를 보실 수 있습니다. 이때 인증코드의 텍스트도 자동으로 저장됩니다. 세션에서. 사용자가 로그인하면 session.getAttribute("kaptchaCode")를 통해 인증코드의 텍스트 내용을 얻을 수 있습니다.

그러나 인증 코드 인터페이스에서 반환되는 콘텐츠는 상대적으로 풍부하여 사진뿐만 아니라 기타 정보일 수도 있습니다. 따라서 서블릿을 직접 구성하는 것은 우리의 요구 사항을 충족할 수 없습니다. 우리가 직접 작성하는 경우에는 확인 코드 이미지를 세션에 직접 저장한 다음 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, " kaptchaCode"); 구성은 실제로 쓸모가 없으며 추가할 필요가 없습니다.

2. 인증 코드 텍스트 맞춤설정🎜🎜물론 인증 코드 텍스트의 구현 클래스만 다음과 같이 제공하면 됩니다. 🎜rrreee🎜이 코드는 이해하기 어렵지 않습니다. 생성된 인증 코드 텍스트는 1+1=?@2와 같은 문자열과 유사합니다. 🎜🎜앞으로는 @를 구분선으로 삼아 사진에 @앞에 문자열 내용을 그리고 세션에서 @뒤 내용을 저장한 후 사용자가 업로드한 내용과 비교해보겠습니다. 🎜🎜물론, 인증 코드 텍스트의 제공 클래스를 수정하기 위해 인증 코드를 구성할 때 다음 속성도 추가해야 합니다. 🎜rrreee🎜구성이 완료되면 인터페이스에서 직접 이 인증 코드를 사용할 수 있습니다. 향후 사용시 주의할 점은 생성된 인증코드 텍스트를 분할하여 처리하고, 일부는 그리기에 사용되고, 일부는 세션에 저장하는 데 사용됩니다. 🎜

위 내용은 SpringBoot+kaptcha로 인증코드를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿