SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證
生成驗(yàn)證碼
提供一個(gè)接口, 這個(gè)接口里,我們將生成的驗(yàn)證碼存入session,然后將驗(yàn)證碼以圖片格式或者base64編碼串返回給調(diào)用端。
校驗(yàn)驗(yàn)證碼
提供一個(gè)接口,這個(gè)接口里,我們收到調(diào)用端傳過來的校驗(yàn)碼,然后從session取出驗(yàn)證碼,兩個(gè)驗(yàn)證碼都全部轉(zhuǎn)小寫,進(jìn)行無大小寫區(qū)分匹配校驗(yàn),返回true/flase 。
1、pom文件中導(dǎo)入hutool-captcha依賴
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.12</version> </dependency>
2、創(chuàng)建后端控制類生成驗(yàn)證碼
創(chuàng)建控制類CommonController類,一方面通過流的方式將隨機(jī)生成的驗(yàn)證碼圖片信息發(fā)送到前端瀏覽器;另一方面將驗(yàn)證碼中的驗(yàn)證信息寫入session中,以方便后續(xù)的驗(yàn)證。
import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.LineCaptcha; import cn.hutool.captcha.ShearCaptcha; import VerifyCodeVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Base64; import java.util.UUID; import java.util.concurrent.TimeUnit; /** * @author author */ @RestController @Api(tags = "驗(yàn)證碼工具類") public class CommonController { @Resource RedisTemplate<String, String> redisTemplate; /** * 方法一 ShearCaptcha * 圖片格式 * session存儲(chǔ) * 接口需添加白名單放行 * * @param request HttpServletRequest */ @GetMapping("/verify") @ApiOperation("生成驗(yàn)證碼") public void verify(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("image/jpeg"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 40, 5, 4); //圖形驗(yàn)證碼寫出,可以寫出到文件,也可以寫出到流 shearCaptcha.write(response.getOutputStream()); //獲取驗(yàn)證碼中的文字內(nèi)容 request.getSession().setAttribute("verifyCode", shearCaptcha.getCode()); } /** * 方法二 LineCaptcha * 圖片格式 * session存儲(chǔ) * 接口需添加白名單放行 * * @param request HttpServletRequest */ @GetMapping("/verifyTwo") @ApiOperation("生成驗(yàn)證碼") public void verifyTwo(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("image/jpeg"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(150, 40, 5, 4); //圖形驗(yàn)證碼寫出,可以寫出到文件,也可以寫出到流 ImageIO.write(lineCaptcha.getImage(), "JPEG", response.getOutputStream()); //獲取驗(yàn)證碼中的文字內(nèi)容 request.getSession().setAttribute("verifyCode", lineCaptcha.getCode()); } /** * 方法三 ShearCaptcha * 圖片的base64編碼字符串 * session存儲(chǔ) * 接口需添加白名單放行 * * @param request HttpServletRequest * @return String */ @GetMapping("/getVerify") @ApiOperation("生成驗(yàn)證碼") public String getVerify(HttpServletRequest request) { //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 40, 5, 4); //獲取驗(yàn)證碼中的文字內(nèi)容 request.getSession().setAttribute("verifyCode", shearCaptcha.getCode()); String base64String = ""; try { base64String = "data:image/png;base64," + shearCaptcha.getImageBase64(); } catch (Exception e) { e.printStackTrace(); } return base64String; } /** * 方法四 LineCaptcha * 圖片的base64編碼字符串 * session存儲(chǔ) * 接口需添加白名單放行 * * @param request HttpServletRequest * @return String */ @GetMapping("/getVerifyTwo") @ApiOperation("生成驗(yàn)證碼") public String getVerifyTwo(HttpServletRequest request) { //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(150, 40, 5, 4); //獲取驗(yàn)證碼中的文字內(nèi)容 request.getSession().setAttribute("verifyCode", lineCaptcha.getCode()); String base64String = ""; try { //返回 base64 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(lineCaptcha.getImage(), "JPEG", bos); byte[] bytes = bos.toByteArray(); Base64.Encoder encoder = Base64.getEncoder(); base64String = "data:image/png;base64," + encoder.encodeToString(bytes); } catch (Exception e) { e.printStackTrace(); } return base64String; } /** * 方法五 ShearCaptcha * 圖片的base64編碼字符串 * redis存儲(chǔ) * 接口需添加白名單放行 * * @return String */ @GetMapping("/getVerifyThree") @ApiOperation("生成驗(yàn)證碼") public VerifyCodeVO getVerifyThree() { String captchaKey = UUID.randomUUID().toString(); //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 40, 5, 0); // 存入redis并設(shè)置過期時(shí)間為30分鐘 redisTemplate.opsForValue().set("captcha:" + captchaKey, shearCaptcha.getCode(), 30L, TimeUnit.MINUTES); //captcha:d6e561a6-7929-4469-8154-008710932f61 String base64String = ""; try { base64String = "data:image/png;base64," + shearCaptcha.getImageBase64(); } catch (Exception e) { e.printStackTrace(); } VerifyCodeVO verifyCodeVO = new VerifyCodeVO(); verifyCodeVO.setCaptchaKey(captchaKey); verifyCodeVO.setCaptchaImg(base64String); return verifyCodeVO; } /** * 方法六 LineCaptcha * 圖片的base64編碼字符串 * redis存儲(chǔ) * 接口需添加白名單放行 * * @return String */ @GetMapping("/getVerifyFour") @ApiOperation("生成驗(yàn)證碼") public VerifyCodeVO getVerifyFour() { String captchaKey = UUID.randomUUID().toString(); //定義圖形驗(yàn)證碼的長、寬、驗(yàn)證碼字符數(shù)、干擾線寬度 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(150, 40, 5, 4); // 存入redis并設(shè)置過期時(shí)間為30分鐘 redisTemplate.opsForValue().set("captcha:" + captchaKey, lineCaptcha.getCode(), 30L, TimeUnit.MINUTES); //captcha:d6e561a6-7929-4469-8154-008710932f61 String base64String = ""; try { //返回 base64 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(lineCaptcha.getImage(), "JPEG", bos); byte[] bytes = bos.toByteArray(); Base64.Encoder encoder = Base64.getEncoder(); base64String = "data:image/png;base64," + encoder.encodeToString(bytes); } catch (Exception e) { e.printStackTrace(); } VerifyCodeVO verifyCodeVO = new VerifyCodeVO(); verifyCodeVO.setCaptchaKey(captchaKey); verifyCodeVO.setCaptchaImg(base64String); return verifyCodeVO; } }
3、實(shí)現(xiàn)驗(yàn)證碼的驗(yàn)證與返回結(jié)果
對(duì)前端輸入的數(shù)據(jù)并發(fā)送到服務(wù)器的驗(yàn)證信息進(jìn)行校驗(yàn),當(dāng)輸入信息與驗(yàn)證碼信息一致則返回true,否則返回false。
/** * session存儲(chǔ) * * @param captchaCode 驗(yàn)證碼 * @param request HttpServletRequest * @return boolean */ @GetMapping("/checkCaptcha") @ApiOperation("驗(yàn)證碼校驗(yàn)") public boolean getCheckCaptcha(@RequestParam("captchaCode") String captchaCode, HttpServletRequest request) { try { // toLowerCase() 不區(qū)分大小寫進(jìn)行驗(yàn)證碼校驗(yàn) String sessionCode = String.valueOf(request.getSession().getAttribute("verifyCode")).toLowerCase(); System.out.println("session里的驗(yàn)證碼:" + sessionCode); String receivedCode = captchaCode.toLowerCase(); System.out.println("用戶的驗(yàn)證碼:" + receivedCode); return !"".equals(sessionCode) && !"".equals(receivedCode) && sessionCode.equals(receivedCode); } catch (Exception e) { return false; } } /** * redis存儲(chǔ) * * @param captchaCode 驗(yàn)證碼 * @param request HttpServletRequest * @return boolean */ @GetMapping("/checkCaptchaTwo") @ApiOperation("驗(yàn)證碼校驗(yàn)") @ApiImplicitParam(value = "Captcha-Key", name = "Captcha-Key", paramType = "header", dataType = "String", required = true) public boolean getCheckCaptchaTwo(@RequestParam("captchaCode") String captchaCode, HttpServletRequest request) { try { // toLowerCase() 不區(qū)分大小寫進(jìn)行驗(yàn)證碼校驗(yàn) String redisCode = String.valueOf(redisTemplate.opsForValue().get("captcha:" + request.getHeader("Captcha-Key"))).toLowerCase(); System.out.println("redisCode里的驗(yàn)證碼:" + redisCode); String receivedCode = captchaCode.toLowerCase(); System.out.println("用戶的驗(yàn)證碼:" + receivedCode); return !"".equals(redisCode) && !"".equals(receivedCode) && redisCode.equals(receivedCode); } catch (Exception e) { return false; } }
Redis存儲(chǔ),返回工具類:
import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data public class VerifyCodeVO implements Serializable { @ApiModelProperty(value = "header頭參數(shù):Captcha-Key") private String captchaKey; @ApiModelProperty(value = "驗(yàn)證碼圖片") private String captchaImg; }
啟動(dòng)應(yīng)用,訪問 http://localhost:8080/verify 即可得到驗(yàn)證碼,如圖:
前端調(diào)用展示:在img標(biāo)簽中src屬性調(diào)用 /verify 接口,將傳過來的圖片驗(yàn)證碼顯示即可。若想換一張顯示(刷新驗(yàn)證碼):在img標(biāo)簽中增加一個(gè)onclick屬性點(diǎn)擊事件即可。
<img src="/verify" id="verifyCode" onclick="refresh()" alt="驗(yàn)證碼" /> <script> /* 刷新驗(yàn)證碼 */ function refresh() { document.getElementById("verifyCode").src = "verify?time=" + new Date().getTime(); } </script>
到此這篇關(guān)于SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證的文章就介紹到這了,更多相關(guān)SpringBoot驗(yàn)證碼生成與驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
web.xml?SpringBoot打包可執(zhí)行Jar運(yùn)行SpringMVC加載流程
這篇文章主要為大家介紹了web.xml?SpringBoot打包可執(zhí)行Jar運(yùn)行SpringMVC加載流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04List集合按某個(gè)屬性或者字段進(jìn)行分組的操作
這篇文章主要介紹了List集合按某個(gè)屬性或者字段進(jìn)行分組的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06bootstrap.yml如何讀取nacos配置中心的配置文件
這篇文章主要介紹了bootstrap.yml讀取nacos配置中心的配置文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Spring boot 整合CXF開發(fā)web service示例
這篇文章主要介紹了Spring boot 整合CXF開發(fā)web service示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05使用JAR包中MANIFEST.MF的注意事項(xiàng)
這篇文章主要介紹了使用JAR包中MANIFEST.MF的注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07MyBatis中操作類對(duì)象的實(shí)現(xiàn)
在MyBatis框架中,操作類對(duì)象是用于執(zhí)行數(shù)據(jù)庫操作的核心對(duì)象,本文主要介紹了MyBatis中操作類對(duì)象的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11關(guān)于SpringBoot簡介、官網(wǎng)構(gòu)建、快速啟動(dòng)的問題
SpringBoot 是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡化Spring應(yīng)用的初始搭建以及開發(fā)過程,這篇文章主要介紹了SpringBoot簡介、官網(wǎng)構(gòu)建、快速啟動(dòng),需要的朋友可以參考下2022-07-07