首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring MVC 圖片驗證碼生成與校驗完整實現

     編輯:Java 相關知識

整體流程

  1. 前端頁面加載 → 請求 /getSysManageLoginCode 獲取圖片
  2. 後端生成驗證碼圖片 → 存入 Session/Cookie → 輸出圖片流
  3. 用戶輸入 → 失焦/提交時請求 /checkimagecode 校驗
  4. 後端比對 Session/Cookie 中值 → 返回 ok/error

前端頁面 (image.jsp)

<img id="codeValidateImg" onclick="flushValidateCode()"/>
<a href="javascript:flushValidateCode();">換一張</a>

<script>
function flushValidateCode() {
    // 加時間戳防緩存
    $('#codeValidateImg').attr('src', '${pageContext.request.contextPath}/getSysManageLoginCode?time=' + new Date());
}

function checkImg(code) {
    $.get('${pageContext.request.contextPath}/checkimagecode', {validateCode: code}, function(data) {
        if (data === 'ok') alert('驗證通過');
        else { alert('驗證碼錯誤'); flushValidateCode(); }
    });
}
</script>

後端控制器

驗證碼生成核心類 (RandomValidateCode)

public class RandomValidateCode {
    private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final int WIDTH = 80, HEIGHT = 26, LINE_COUNT = 40, CHAR_COUNT = 4;

    public void getRandcode(HttpServletRequest request, HttpServletResponse response, String key) {
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();

        // 1. 填充背景
        g.fillRect(0, 0, WIDTH, HEIGHT);
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        g.setColor(getRandColor(110, 133));

        // 2. 畫干擾線
        for (int i = 0; i <= LINE_COUNT; i++) drowLine(g);

        // 3. 畫隨機字符
        StringBuilder code = new StringBuilder();
        for (int i = 1; i <= CHAR_COUNT; i++) code.append(drowString(g, i));

        // 4. 存儲驗證碼(二選一)
        // Cookie 方式(不安全,易被竊取)
        response.addCookie(new Cookie(key, code.toString()));
        // Session 方式(推薦)
        request.getSession().setAttribute(key, code.toString());

        // 5. 輸出圖片流
        g.dispose();
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", out);
            response.setContentLength(out.size());
            response.getOutputStream().write(out.toByteArray());
        } catch (IOException e) { e.printStackTrace(); }
    }

    private Color getRandColor(int fc, int bc) { ... }
    private String drowString(Graphics g, int i) { ... }
    private void drowLine(Graphics g) { ... }
}

安全性升級建議

  1. 棄用 Cookie 存儲:驗證碼暴露在客戶端,必須用 Session 或 Redis
  2. 大小寫不敏感:equalsIgnoreCase 提升用戶體驗
  3. 限流與過期:同一 IP 限制請求頻率,驗證碼 60 秒過期
  4. 防暴力破解:連續錯誤 N 次鎖定賬號/IP,需圖形驗證碼+短信雙因子
  5. 生產環境:建議接入成熟方案(如 Google reCAPTCHA、hCaptcha、滑塊驗證)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved