欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?Boot實(shí)現(xiàn)登錄驗(yàn)證碼功能的案例詳解

 更新時(shí)間:2022年08月10日 10:57:42   作者:不斷前進(jìn)的皮卡丘  
驗(yàn)證碼的作用可以有效防止其他人對(duì)某一個(gè)特定的注冊(cè)用戶用特定的程序暴力破解方式進(jìn)行不斷的登錄嘗試,接下來通過本文給大家介紹Spring?Boot實(shí)現(xiàn)登錄驗(yàn)證碼功能,需要的朋友可以參考下

驗(yàn)證碼的作用

驗(yàn)證碼的作用:可以有效防止其他人對(duì)某一個(gè)特定的注冊(cè)用戶用特定的程序暴力破解方式進(jìn)行不斷的登錄嘗試
我們其實(shí)很經(jīng)常看到,登錄一些網(wǎng)站其實(shí)是需要驗(yàn)證碼的,比如牛客,QQ等。使用驗(yàn)證碼是現(xiàn)在很多網(wǎng)站通行的一種方式,這個(gè)問題是由計(jì)算機(jī)生成并且評(píng)判的,但是必須只有人類才能解答,因?yàn)橛?jì)算機(jī)無法解答驗(yàn)證碼的問題,所以回答出問題的用戶就可以被認(rèn)為是人類。
驗(yàn)證碼一般用來防止批量注冊(cè)。

案例要求

驗(yàn)證碼本質(zhì):后端程序隨機(jī)驗(yàn)證碼
圖片的創(chuàng)建:
—java api手動(dòng)創(chuàng)建圖片
—JavaScript 前端創(chuàng)建圖片
驗(yàn)證碼的刷新
—添加JavaScript的點(diǎn)擊事件,重新請(qǐng)求驗(yàn)證碼圖片

前端頁面準(zhǔn)備

因?yàn)樯婕暗絡(luò)Query,所以需要在resources/static創(chuàng)建目錄,存放jQuery庫

在這里插入圖片描述

準(zhǔn)備login.html頁面

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>用戶登錄</title>
    <!--引入jQuery -->
    <script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
  </head>
  <body>
    <h2>用戶登錄</h2>
    <form action="/login" method="post">
      用戶名:<input type="text" name="username"><br><br>
      密碼  :<input type="password" name="password"><br><br>
      驗(yàn)證碼:<input id="identify-input" type="text" name="identifyCode">
      <img id="identify-img" src="/identifyImage"><br><br>
      <input type="submit" value="登錄">
    </form>
    <!--綁定點(diǎn)擊事件 -->
    <script>
      $("#identify-img").on('click',function (){
        // 點(diǎn)擊驗(yàn)證碼那個(gè)圖片的時(shí)候,我們輸入的驗(yàn)證碼那個(gè)框就會(huì)清空
        $('#identify-input').val('')
        //而且我們點(diǎn)擊驗(yàn)證碼的時(shí)候,希望它可以改變驗(yàn)證碼內(nèi)容,其實(shí)是通過發(fā)送新請(qǐng)求來改變驗(yàn)證碼內(nèi)容
        $('#identify-img').attr('src','/identifyImage?'+Math.random())
      })
      
    </script>
  </body>
</html>

隨機(jī)驗(yàn)證碼工具類

public class IdentifyCodeUtils {
    //設(shè)置圖片寬
    private int width = 95;
    //設(shè)置圖片高度
    private int height = 25;
    //設(shè)置干擾線數(shù)量
    private int lineSize = 40;
    //隨機(jī)產(chǎn)生數(shù)字和字母組合的字符串
    private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private Random random = new Random();
    
    /**
    * 獲得字體
    */
    private Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
    }
    
    /**
    * 獲得顏色
    */
    private Color getRandColor(int fc, int bc) {
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }
    
    /**
    * 獲取驗(yàn)證碼
    *
    * @return
    */
    public String getIdentifyCode() {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            char c = randString.charAt(random.nextInt(randString.length()));
            buffer.append(c);
        }
        return buffer.toString();
    }
    
    /**
    * 生成隨機(jī)圖片
    *
    * @param identifyCode
    * @return
    */
    public BufferedImage getIdentifyImage(String identifyCode) {
        //BufferedImage類是具有緩沖區(qū)的Image類,Image類是用來描述圖像信息的類
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        //產(chǎn)生Image對(duì)象的Graphics對(duì)象,改對(duì)象可以在圖像上進(jìn)行各種繪制操作
        Graphics graphics = image.getGraphics();
        //圖片大小
        graphics.fillRect(0, 0, width, height);
        //字體大小
        graphics.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        //字體顏色
        graphics.setColor(getRandColor(110, 133));
        //繪制干擾線
        for (int i = 0; i <= lineSize; i++) {
            drawLine(graphics);
        }
        //繪制隨機(jī)字符
        drawString(graphics, identifyCode);
        graphics.dispose();
        return image;
        
    }
    
    /**
    * 繪制字符串
    */
    private void drawString(Graphics g, String identifyCode) {
        for (int i = 0; i < identifyCode.length(); i++) {
            g.setFont(getFont());
            g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
                                 .nextInt(121)));
            g.translate(random.nextInt(3), random.nextInt(3));
            g.drawString(String.valueOf(identifyCode.charAt(i)), 13 * i + 20, 18);
        }
        
        
    }
    
    /**
    * 響應(yīng)驗(yàn)證碼圖片
    *
    * @param identifyImg
    * @param response
    */
    public void responseIdentifyImg(BufferedImage identifyImg, HttpServletResponse response) {
        //設(shè)置響應(yīng)類型,告訴瀏覽器輸出的內(nèi)容是圖片
        response.setContentType("image/jpeg");
        //設(shè)置響應(yīng)頭信息,告訴瀏覽器不用緩沖此內(nèi)容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        try {
            //把內(nèi)存中的圖片通過流動(dòng)形式輸出到客戶端
            ImageIO.write(identifyImg, "JPEG", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
    * 繪制干擾線
    */
    private void drawLine(Graphics graphics) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        graphics.drawLine(x, y, x + xl, y + yl);
    }
}

后端控制器

@Controller
public class UserController {
    @RequestMapping("/loginShow")
    public String loginShow(){
        return "login.html";
    }
    @PostMapping("/login")
    public String login(String username,String password,String identifyCode,HttpSession session){
        System.out.println("用戶名:"+username);
        System.out.println("密碼:"+password);
        System.out.println("驗(yàn)證碼:"+identifyCode);
        //從session中取出驗(yàn)證碼
        String sessionCode = (String)session.getAttribute("identifyFyCode");
        if (identifyCode.equalsIgnoreCase(sessionCode)){
            System.out.println("驗(yàn)證碼正確");
            //進(jìn)行登錄判斷的邏輯大家自己寫,這里就不演示了
        }else{
            System.out.println("驗(yàn)證碼錯(cuò)誤");
            //重定向到登錄畫面
            return "redirect:/loginShow";
        }
         return "";
    }

    /**
     * 給前端返回一個(gè)驗(yàn)證碼圖片
     * @return
     */
    @RequestMapping("/identifyImage")
    public void identifyImage(HttpServletResponse response, HttpSession session){
        //創(chuàng)建隨機(jī)驗(yàn)證碼
        IdentifyCodeUtils utils = new IdentifyCodeUtils();
        String identifyCode = utils.getIdentifyCode();
        //session存入驗(yàn)證碼
        session.setAttribute("identifyCode", identifyCode);
        //根據(jù)驗(yàn)證碼創(chuàng)建圖片
        BufferedImage identifyImage = utils.getIdentifyImage(identifyCode);
        //回傳給前端
        utils.responseIdentifyImg(identifyImage,response);

    }
}

測(cè)試

在這里插入圖片描述

當(dāng)我們點(diǎn)擊驗(yàn)證碼這個(gè)圖片的時(shí)候,它就會(huì)生成新驗(yàn)證碼
并且如果我們?cè)谳斎肟蛑腥绻袑戲?yàn)證碼的話,當(dāng)我們點(diǎn)擊驗(yàn)證碼圖片,它就會(huì)把輸入框內(nèi)容清空(大家自己測(cè)試)

到此這篇關(guān)于Spring Boot實(shí)現(xiàn)登錄驗(yàn)證碼功能的案例詳解的文章就介紹到這了,更多相關(guān)springboot登錄驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí)的代碼示例

    使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí)的代碼示例

    Sentinel是面向分布式、多語言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,本文將詳細(xì)為大家介紹如何使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí),文中有相關(guān)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • IDEA 中創(chuàng)建Spring Data Jpa 項(xiàng)目的示例代碼

    IDEA 中創(chuàng)建Spring Data Jpa 項(xiàng)目的示例代碼

    這篇文章主要介紹了IDEA 中創(chuàng)建Spring Data Jpa 項(xiàng)目的示例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring注解與P/C命名空間超詳細(xì)解析

    Spring注解與P/C命名空間超詳細(xì)解析

    Spring注解方式減少了配置文件內(nèi)容,更加便于管理,并且使用注解可以大大提高了開發(fā)效率!注解本身是沒有功能的,和xml一樣,注解和xml都是一種元數(shù)據(jù),元數(shù)據(jù)即解釋數(shù)據(jù)的數(shù)據(jù),也就是所謂的配置
    2022-11-11
  • Springboot 集成 lombok.jar過程解析

    Springboot 集成 lombok.jar過程解析

    這篇文章主要介紹了Springboot 集成 lombok.jar過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Mybatis-Plus實(shí)體類注解方法與mapper層和service層的CRUD方法

    Mybatis-Plus實(shí)體類注解方法與mapper層和service層的CRUD方法

    CRUD是指在做計(jì)算處理時(shí)的增加(Create)、讀取查詢(Retrieve)、更新(Update)和刪除(Delete)幾個(gè)單詞的首字母簡(jiǎn)寫。主要被用在描述軟件系統(tǒng)中DataBase或者持久層的基本操作功能,下面讓我們一起看看吧
    2022-03-03
  • 簡(jiǎn)單談?wù)凧VM、JRE和JDK的區(qū)別與聯(lián)系

    簡(jiǎn)單談?wù)凧VM、JRE和JDK的區(qū)別與聯(lián)系

    簡(jiǎn)單的說JDK是用于開發(fā)的而JRE是用于運(yùn)行Java程序的。JDK和JRE都包含了JVM,從而使得我們可以運(yùn)行Java程序。JVM是Java編程語言的核心并且具有平臺(tái)獨(dú)立性。
    2016-05-05
  • feign客戶端HTTP狀態(tài)碼為204時(shí)?響應(yīng)體被忽略的問題

    feign客戶端HTTP狀態(tài)碼為204時(shí)?響應(yīng)體被忽略的問題

    這篇文章主要介紹了feign客戶端HTTP狀態(tài)碼為204時(shí)?響應(yīng)體被忽略的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 詳解JAVA如何實(shí)現(xiàn)樂觀鎖以及CAS機(jī)制

    詳解JAVA如何實(shí)現(xiàn)樂觀鎖以及CAS機(jī)制

    悲觀鎖和樂觀鎖其實(shí)本質(zhì)都是一種思想,在JAVA中對(duì)于悲觀鎖的實(shí)現(xiàn)大家可能都很了解,可以通過synchronized、ReentrantLock加鎖實(shí)現(xiàn),本文不展開講解了。那么樂觀鎖在JAVA中是如何實(shí)現(xiàn)的呢?底層的實(shí)現(xiàn)機(jī)制又是什么呢?本文就來和大家詳細(xì)講講
    2022-12-12
  • Mybatis設(shè)置sql打印日志的多種方法

    Mybatis設(shè)置sql打印日志的多種方法

    這篇文章主要介紹了Mybatis設(shè)置sql打印日志,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java數(shù)據(jù)類型的規(guī)則

    Java數(shù)據(jù)類型的規(guī)則

    這篇文章主要介紹了Java數(shù)據(jù)類型的規(guī)則的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-12-12

最新評(píng)論