驗證碼案例
學了Spring MVC ,配置 相關章節, 現可以嘗試寫一個前后端交互的驗證碼
文章目錄
- 驗證碼案例
- 前言
- 一、驗證碼是什么?
- 二、需求
- 1.引入依賴
- 2.導入前端頁面
- 3.約定前后段交互接口
- 三、代碼解析
- Controller
- model
- application.xml
- 四丶結果
- 五丶總結
前言
提示:這里可以添加本文要記錄的大概內容:
頁面如下圖所示
1.頁面生成驗證碼
2.輸入驗證碼,點擊提交,驗證用戶輸入驗證碼是否正確,正確則頁面跳轉
提示:以下是本篇文章正文內容,下面案例可供參考
一、驗證碼是什么?
驗證碼,是來區分用戶是計算機還是人的公共全自動程序,可以防止:惡意破解密碼,刷票,等有效防止某個黑客對特定用戶進行暴力登錄,這個問題必須只有人類才能解答,驗證碼花樣百出,下面我們將采用扭曲干擾驗證碼來實現前后端交互的接口
二、需求
1.引入依賴
代碼如下(示例):
<dependencies>//SpingWeb 框架<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>// lombok 自動生成<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>//test 測試方法<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>//驗證碼 相關的類 封裝好了的 直接用<dependency><groupId>cn.hutool</groupId><artifactId>hutool-captcha</artifactId><version>5.8.26</version></dependency></dependencies>
把這段代碼加入pom.xml文件中即可,但是要把里面的注釋刪了 ,否則會出錯
2.導入前端頁面
代碼如下(示例):
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>驗證碼</title><style>#inputCaptcha {height: 30px;vertical-align: middle; }#verificationCodeImg{vertical-align: middle; }#checkCaptcha{height: 40px;width: 100px;}</style>
</head><body><h1>輸入驗證碼</h1><div id="confirm"><input type="text" name="inputCaptcha" id="inputCaptcha"><img id="verificationCodeImg" src="/captcha/getCaptcha" style="cursor: pointer;" title="看不清?換一張" /><input type="button" value="提交" id="checkCaptcha"></div><script src="https://code.jquery.com/jquery-3.7.1.min.js"></script><script>$("#verificationCodeImg").click(function(){$(this).hide().attr('src', '/captcha/getCaptcha?dt=' + new Date().getTime()).fadeIn();});$("#checkCaptcha").click(function () {$.ajax({url:"/captcha/check",type:"post",data:{captcha:$("#inputCaptcha").val()},success: function(result){if(result==true){location.href="/success.html"}else{alert("驗證碼錯誤");}}})});});</script>
</body></html>
success.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>驗證成功頁</title>
</head>
<body><h1>驗證成功</h1>
</body>
</html>
3.約定前后段交互接口
需求分析
后端需要提供兩個服務
- 生成驗證碼,并返回驗證碼;
- 校驗驗證碼是否正確;
接口定義
1.生成驗證碼
請求:
請求URL:/captcha/getCaptcha
響應:驗證碼圖片內容
2.校驗驗證碼是否正確
請求:
請求URL:/captcha/check
請求參數:captcha ,用戶傳過來的驗證碼
響應: true / false
三、代碼解析
Controller
@RestController
@RequestMapping("/captcha")
public class CaptchaController {//注入配置 對象 , 一些常量從里面讀取@Autowiredprivate CaptchaProperties cp;//易鳳種 華為msprivate static long VALID_TIME_OUT = 60*1000;@RequestMapping("/getCaptcha")public void getCaptcha(HttpSession session, HttpServletResponse response) {//生成驗證碼 ,并把驗證碼寫入瀏覽器中//定義圖形驗證碼的長和寬CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(cp.getWidth(), cp.getHeight(), cp.getCodeCount(), cp.getCilceCount());//打印驗證碼String code = captcha.getCode();System.out.println(code);//驗證碼 , 當前時間 存入Sessionsession.setAttribute(cp.getSession().getCode(), code);session.setAttribute(cp.getSession().getDate(), new Date());try {//把驗證碼寫到瀏覽器中captcha.write(response.getOutputStream());} catch (IOException e) {throw new RuntimeException(e);}}//校驗驗證碼,獲取生成的驗證碼 寫給Session@RequestMapping("/check")public boolean check(String captcha,HttpSession session) {//校驗是否為空,防止equls空指針if(!StringUtils.hasLength(captcha)){return false;}//從Session中讀取值String code = (String) session.getAttribute(cp.getSession().getCode());Date date = (Date) session.getAttribute(cp.getSession().getDate());//校驗獲取驗證碼的時間 和 校驗時間 的差值不能超過一分鐘if(date == null || (System.currentTimeMillis() - date.getTime()) > VALID_TIME_OUT){return false;}return captcha.equalsIgnoreCase(code);}
}
解析 :接口getCaptcha ,用來生成驗證碼(從hutool上面cv),那么如何將生成的驗證碼傳給另一個接口呢 ? 設置Session,response是用來把驗證碼寫入到文件/瀏覽器中的 ,前端用來改一下img中圖片的src屬性即可獲取
Controller 從model中獲取配置信息, 需要依賴注入 ,各種常量屬性,和存儲在Session中的“key
model
@Data
@Configuration
@ConfigurationProperties(prefix = "captcha")
//讀取配置的信息
public class CaptchaProperties {private Integer width;private Integer height;private Integer codeCount;private Integer cilceCount;private Session session;@Datapublic static class Session {private String code;private String date;}
}
配置對象的接口 ,用來獲取配置中的信息(對象) ,并封裝成一個類,需要用到@configurationproperties(“prefix="對象名"”)并且設置對象中的屬性,內部類
,注意使用內部類 一般要加上 public static 或者會出現錯誤 具體原因后續再說
@Data 是用來生成 get/set 方法的,來自于lombok依賴
application.xml
captcha:width: 100height: 40codeCount: 4circleCount: 40Session:key: SESSION_CAPTCHA_KEYdate: SESSION_CAPTCHA_DATE
配置相關信息,配置了驗證碼的相關屬性,前后端交互時的Session , 使用 key - value 的形式
四丶結果
點擊“提交”,跳轉頁面 成功!!
五丶總結
問題:
- HttpSErvletResponse 是什么 ? 為什么能寫入到瀏覽器 ?
- 在驗證代碼時,在一個接口中把驗證碼傳給Session ,另一個接口為什么能從Session中獲取到?
- 在使用內部類時, 為什么 要設置 public ? 為什么 要用static才能運行?
- [ ]
注意:
- System.currentTimeMillis() 表示當前時間 ,類型為long , 單位為ms