Rumah  >  Artikel  >  Java  >  Bagaimana untuk melaksanakan kod pengesahan dengan SpringBoot+kaptcha

Bagaimana untuk melaksanakan kod pengesahan dengan SpringBoot+kaptcha

WBOY
WBOYke hadapan
2023-05-25 14:25:221600semak imbas

1. Penggunaan asas

kaptcha ialah alat penjanaan kod pengesahan yang sangat lama? Bertarikh sejak tahun 2006.

Selepas bertahun-tahun, ia bukan sahaja tidak sunyi tetapi ia masih digunakan oleh ramai orang, yang menunjukkan daya hidup dan layak untuk kita pelajari.

Untuk kemudahan, kami mencipta projek Spring Boot untuk menunjukkan penggunaannya.

Mula-mula buat projek Spring Boot baharu, dan kemudian tambahkan kebergantungan kaptcha, seperti berikut:

<dependency>
  <groupId>com.github.penggle</groupId>
  <artifactId>kaptcha</artifactId>
  <version>2.3.2</version>
</dependency>

Seterusnya kami hanya perlu menyediakan Bean untuk mengkonfigurasi Kaptcha, seperti berikut:

@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;
    }
}

Konfigurasikan pelbagai nilai atribut imej kod pengesahan dalam DefaultKaptcha. Maksud setiap atribut diulas dalam kod, jadi saya tidak akan mengatakan lebih lanjut.

Seterusnya kami mengembalikan imej kod pengesahan dalam antara muka, seperti berikut:

@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());
}

Saya menulis imej ke bahagian hadapan dalam bentuk strim IO Sudah tentu, ia juga boleh ditukar ke dalam Base64 Rentetan yang dikembalikan ke hujung hadapan juga OK.

Tunggu, sepertinya ada yang hilang!

Kami tidak menyimpan teks kod pengesahan yang dijana dalam sesi, supaya ia tidak dapat disahkan semasa log masuk. Sesetengah rakan mungkin berkata, adakah ini tidak mudah? Tidak cukupkah dengan hanya menyimpannya dalam antara muka?

NONONO!

Lihat, apabila kita mengkonfigurasi kacang DefaultKaptcha, terdapat barisan kod sedemikian properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); Baris kod ini bermakna teks kod pengesahan yang dijana akan disimpan secara automatik dalam sesi, dan KEY sesi adalah kaptchaCode. Walau bagaimanapun, dalam ujian sebenar, anda akan mendapati bahawa kod di atas tidak menyimpan teks yang dijana oleh kod pengesahan ke dalam sesi.

Alasannya ialah alat Kaptcha sebenarnya menyediakan Servlet yang menjana imej kod pengesahan Jika kami terus menggunakan kod pengesahan yang disediakan oleh Servlet, maka konfigurasi di atas akan berkuat kuasa, jika anda mahu Untuk mengkonfigurasi Servlet yang disediakan oleh Kaptcha, kaedahnya adalah seperti berikut:

@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;
}

Selepas projek dimulakan, akses terus /img untuk melihat imej kod pengesahan Pada masa ini, teks kod pengesahan akan juga disimpan secara automatik dalam sesi. Apabila pengguna log masuk, kandungan teks kod pengesahan boleh diperoleh melalui session.getAttribute("kaptchaCode").

Walau bagaimanapun, banyak kali kandungan yang dikembalikan oleh antara muka kod pengesahan agak kaya, yang mungkin bukan sahaja gambar, tetapi juga maklumat lain. Oleh itu, mengkonfigurasi secara langsung Servlet tidak dapat memenuhi keperluan kami Kami hanya boleh menulis antara muka kod pengesahan sendiri Jika kami menulisnya sendiri, kami perlu menyimpan sendiri imej kod pengesahan ke dalam sesi, jadi konfigurasi properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); sebenarnya tidak berguna. Tak perlu tambah.

2. Sesuaikan teks kod pengesahan

Sudah tentu, kami juga boleh menyesuaikan teks kod pengesahan Kami hanya perlu menyediakan kelas pelaksanaan teks kod pengesahan, seperti berikut:

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

Kod ini tidak sukar difahami Teks kod pengesahan yang dijana adalah serupa dengan rentetan seperti 1+1=?@2.

Pada masa hadapan, @ akan digunakan sebagai garis pemisah, kandungan rentetan di hadapan @ akan dilukis pada gambar, kandungan selepas @ akan disimpan dalam sesi, dan dibandingkan dengan kandungan yang dimuat naik oleh pengguna.

Sudah tentu, kami juga perlu menambah atribut berikut semasa mengkonfigurasi kod pengesahan untuk mengubah suai kelas yang menyediakan teks kod pengesahan:

properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "org.javaboy.tienchin.framework.config.KaptchaTextCreator");

Selepas konfigurasi selesai, kod pengesahan ini akan digunakan secara langsung dalam antara muka pada masa hadapan Itu sahaja Apabila menggunakannya, beri perhatian untuk membahagikan teks kod pengesahan yang dijana dan memprosesnya sebahagian daripadanya digunakan untuk melukis dan sebahagian daripadanya digunakan untuk menyimpannya dalam sesi.

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan kod pengesahan dengan SpringBoot+kaptcha. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam