SpringMVC 中使用 Kaptcha 簡易完成圖形驗證碼

前言

圖形驗證碼是驗證碼(CAPTCHA)的一種。驗證碼(CAPTCHA)是 Completely Automated Public Turing test to tell Computers and Humans Apart的縮寫,它是一種區分電腦或人類的自動程式。

而我們可以使用 kaptcha 來生成驗證碼,它是一個基於 SimpleCaptcha 的開源程式碼,使用它我們可以快速的生成各式各樣的驗證碼。

實作

  1. 下載 kaptcha 資源
    下載連結:https://code.google.com/archive/p/kaptcha/downloads
    解壓縮之後將 kaptcha-2.3.2.jar 移至專案底下(放置位置:WEB-INF>lib)

  2. 配置文件
    接著我們需要配置 kaptcha 的 servlet 還有樣式,可直接在 spring-servlet.xml 中貼上:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
    <property name="config">
    <bean class="com.google.code.kaptcha.util.Config">
    <constructor-arg>
    <props>
    <prop key="kaptcha.image.width">65</prop> //驗證碼圖片寬度
    <prop key="kaptcha.image.height">30</prop> // 驗證碼圖片高度
    <prop key="kaptcha.textproducer.font.size">25</prop>// 字體大小
    <prop key="kaptcha.textproducer.font.color">red</prop> // 顏色
    <prop key="kaptcha.textproducer.font.names">Arial</prop> // 字體
    <prop key="kaptcha.textproducer.char.length">4</prop> // 驗證碼長度
    <prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.ShadowGimpy</prop> // 驗證碼樣式引擎,預設 WaterRipple
    <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>
    </props>
    </constructor-arg>
    </bean>
    </property>
    </bean>

詳細的配置屬性如下:

配置屬性 敘述 可輸入值 預設值
kaptcha.border 图片邊框 yes,no yes
kaptcha.border.color 邊框顏色 rgb 或者 white,black,blue black
kaptcha.border.thickness 邊框厚度 >0 1
kaptcha.image.width 驗證碼圖片寬 >0 200
kaptcha.image.height 驗證碼圖片高 >0 50
kaptcha.producer.impl 驗證碼圖片實現類 com.google.code.kaptcha.impl.DefaultKaptcha
kaptcha.textproducer.impl 驗證碼文字實現類 com.google.code.kaptcha.text.impl.DefaultTextCreator
kaptcha.textproducer.char.string 驗證碼文字集合 abcde2345678gfynmnpwx
kaptcha.textproducer.char.length 驗證碼字元長度 5
kaptcha.textproducer.font.names 字體 Arial, Courier
kaptcha.textproducer.font.size 字體大小 40px
kaptcha.textproducer.font.color 字體顏色 r,g,b 或者 white,black,blue black
kaptcha.textproducer.char.space 字元間隔 2
kaptcha.noise.impl 干擾實現類 com.google.code.kaptcha.impl.DefaultNoise
kaptcha.noise.color 干擾的顏色 r,g,b 或者 white,black,blue black
kaptcha.obscurificator.impl 圖片樣式 水纹com.google.code.kaptcha.impl.WaterRipple
魚眼com.google.code.kaptcha.impl.FishEyeGimpy
陰影com.google.code.kaptcha.impl.ShadowGimpy
com.google.code.kaptcha.impl.WaterRipple
kaptcha.background.impl 背景實現類 com.google.code.kaptcha.impl.DefaultBackground
kaptcha.background.clear.from 背景顏色漸變,開始顏色 lightGray
kaptcha.background.clear.to 背景顏色漸變,結束顏色 white
kaptcha.word.impl 文字渲染器 com.google.code.kaptcha.text.impl.DefaultWordRenderer
kaptcha.session.key session key KAPTCHA_SESSION_KEY
kaptcha.session.date session date KAPTCHA_SESSION_DATE
  1. 撰寫 controller 層
    配置好設定後,我們就可以來設定控制層,
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    package controller;

    @Controller
    public class UtilController {
    @Autowired
    private Producer verifyCodeProducer;

    @RequestMapping(path = "/getVerifyCodeImage", method = RequestMethod.GET)
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) {
    response.setContentType("image/jpeg"); // 設定為回傳一個 jpg 檔案
    String capText = verifyCodeProducer.createText(); // 建立驗證碼文字
    BufferedImage bi = verifyCodeProducer.createImage(capText) ;// 使用驗證碼文字建立驗證碼圖片

    HttpSession session = request.getSession();
    session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);

    ServletOutputStream out = null;
    try {
    out = response.getOutputStream(); // 取得 ServletOutputStream 實例
    ImageIO.write(bi, "jpg", out); // 輸出圖片
    out.flush(); // 強制請求清空緩存區
    } catch (Exception e) {
    System.out.println(e);
    } finally {
    IOUtils.closeQuietly(out);
    }
    }
    }

接著我們輸入:http://localhost:8080/{你的專案名稱}/getVerifyCodeImage,就可以看到我們剛剛設定好的圖片。

  1. 撰寫 view 層
    JSP 的部分

    1
    2
    3
    4
    5
    6
    7
    <!-- Login.jsp -->
    <div class="chknumber">
    輸入驗證碼: <input name="kaptcha" type="text"
    id="kaptcha" maxlength="4" class="chknumber_input" />
    <img src="${pageContext.request.contextPath}/getVerifyCodeImage" id="kaptchaImage"/>
    <a href="#" onclick="changeCode()">看不到嗎?點我換驗證碼</a>
    </div>

    JS的部分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $(function(){         
    $('#kaptchaImage').click(function () {
    $(this).hide().attr('src', '${pageContext.request.contextPath}/getVerifyCodeImage?' + Math.floor(Math.random()*100) ).fadeIn();
    });
    });

    function changeCode() {
    $('#kaptchaImage').hide().attr('src', '${pageContext.request.contextPath}/getVerifyCodeImage?' + Math.floor(Math.random()*100) ).fadeIn();
    }

    *註解:因為瀏覽器的快取會存取圖片,所以需要在request 後方加上隨機值讓他像新的請求。

  2. 取的我們設定的驗證碼
    前面在設定驗證碼時,我們有將其存在 Session 中,所以我們在其他 Controller 中透過getSession() 取得剛剛設定的驗證碼字元。

    1
    2
    String kaptchaExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
    System.out.println(kaptchaExpected);

    結語

    關於CAPTCHA 有個有趣的小故事,設計出 CAPTCHA 的馮安將這個系統簡稱為 CAPTCHA 是因為CAPTCHA聽起來像是英文的「抓到你了」。

參考資料

kaptcha文件 - HowToUse.wiki
https://code.google.com/archive/p/kaptcha/wikis/HowToUse.wiki

Spring mvc框架下使用kaptcha生成驗證碼
https://www.programminghunter.com/article/3631604970/

spring mvc 使用kaptcha配置生成驗證碼例項
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/310104/


SpringMVC 中使用 Kaptcha 簡易完成圖形驗證碼
https://shinyu0430.github.io/2022/05/06/springKaptcha/
作者
Mavis Tsai
發布於
2022年5月6日
許可協議