SpringBoot+kaptcha實(shí)現(xiàn)驗(yàn)證碼花式玩法詳解
在 vhr 項(xiàng)目中,松哥也跟大家講了驗(yàn)證碼的用法,不過(guò)那個(gè)里邊的驗(yàn)證碼是我們自己寫(xiě)的,其實(shí)功能也還算完整,夠用。不過(guò)現(xiàn)在各個(gè)網(wǎng)站的驗(yàn)證碼玩法花樣越來(lái)越多,加上最近在搞的 TienChin 項(xiàng)目用的驗(yàn)證碼是一個(gè)老牌開(kāi)源庫(kù) kaptcha,所以松哥決定還是花點(diǎn)時(shí)間,跟大家聊聊 kaptcha 的用法,畢竟這個(gè)已經(jīng)有 16 年歷史的玩意還在有人用,說(shuō)明它的功能還是相當(dāng)強(qiáng)大的。
1. 基本用法
kaptcha 是一個(gè)非常老牌的驗(yàn)證碼生成工具,多老呢?可以追溯到 2006 年。
這么多年過(guò)去了,它不僅沒(méi)有落寞反而還在被不少人使用,足以說(shuō)明它的生命力了,值得我們來(lái)研究下。
方便起見(jiàn),我們整一個(gè) Spring Boot 工程來(lái)演示它的用法。
首先新建一個(gè) Spring Boot 工程,然后加入 kaptcha 的依賴,如下:
<dependency> ??<groupId>com.github.penggle</groupId> ??<artifactId>kaptcha</artifactId> ??<version>2.3.2</version> </dependency>
接下來(lái)我們只需要提供一個(gè)配置 Kaptcha 的 Bean 即可,如下:
@Configuration public?class?KaptchaConfig?{ ????@Bean(name?=?"captchaProducer") ????public?DefaultKaptcha?getKaptchaBean()?{ ????????DefaultKaptcha?defaultKaptcha?=?new?DefaultKaptcha(); ????????Properties?properties?=?new?Properties(); ????????//?是否有邊框?默認(rèn)為true?我們可以自己設(shè)置yes,no ????????properties.setProperty(KAPTCHA_BORDER,?"yes"); ????????//?驗(yàn)證碼文本字符顏色?默認(rèn)為Color.BLACK ????????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR,?"black"); ????????//?驗(yàn)證碼圖片寬度?默認(rèn)為200 ????????properties.setProperty(KAPTCHA_IMAGE_WIDTH,?"160"); ????????//?驗(yàn)證碼圖片高度?默認(rèn)為50 ????????properties.setProperty(KAPTCHA_IMAGE_HEIGHT,?"60"); ????????//?驗(yàn)證碼文本字符大小?默認(rèn)為40 ????????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE,?"38"); ????????//?KAPTCHA_SESSION_KEY ????????properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY,?"kaptchaCode"); ????????//?驗(yàn)證碼文本字符長(zhǎng)度?默認(rèn)為5 ????????properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH,?"4"); ????????//?驗(yàn)證碼文本字體樣式?默認(rèn)為new?Font("Arial",?1,?fontSize),?new?Font("Courier",?1,?fontSize) ????????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES,?"Arial,Courier"); ????????//?圖片樣式?水紋com.google.code.kaptcha.impl.WaterRipple?魚(yú)眼com.google.code.kaptcha.impl.FishEyeGimpy?陰影com.google.code.kaptcha.impl.ShadowGimpy ????????properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL,?"com.google.code.kaptcha.impl.ShadowGimpy"); ????????Config?config?=?new?Config(properties); ????????defaultKaptcha.setConfig(config); ????????return?defaultKaptcha; ????} }
DefaultKaptcha 中配置驗(yàn)證碼圖片的各個(gè)屬性值。各個(gè)屬性的含義,代碼中都有注釋,我就不再多說(shuō)了。
接下來(lái)我們?cè)诮涌谥蟹祷仳?yàn)證碼圖片,如下:
@Autowired DefaultKaptcha?defaultKaptcha; @GetMapping("/img") public?void?getKaptcha(HttpServletResponse?resp)?throws?IOException?{ ????String?text?=?defaultKaptcha.createText(); ????BufferedImage?image?=?defaultKaptcha.createImage(text); ????ImageIO.write(image,?"jpg",?resp.getOutputStream()); }
我這里是通過(guò) IO 流的形式將圖片寫(xiě)到前端的,當(dāng)然也可以將之轉(zhuǎn)為一個(gè) Base64 字符串返回到前端,一樣也是 OK 的。
等等,似乎少了什么!
我們沒(méi)有把生成的驗(yàn)證碼文本存入到 session 中去,這樣一會(huì)登錄的時(shí)候沒(méi)法驗(yàn)證,有小伙伴可能會(huì)說(shuō),這還不簡(jiǎn)單?接口里邊存一下不就行了?
NONONO!
大家看,當(dāng)我們配置 DefaultKaptcha bean 的時(shí)候,其中有這么一行代碼 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
,這行代碼的意思就是說(shuō)會(huì)自動(dòng)將生成的驗(yàn)證碼文本存入到 session 中,并且 session 的 KEY 是 kaptchaCode。但是在實(shí)際測(cè)試中,大家會(huì)發(fā)現(xiàn)上面的代碼并不會(huì)將驗(yàn)證碼生成的文本存入到 session 中。
原因在于 Kaptcha 工具實(shí)際上自己提供了一個(gè)生成驗(yàn)證碼圖片的 Servlet,如果我們直接使用它自己提供的驗(yàn)證碼 Servlet,那么上面這個(gè)配置才會(huì)生效,在 Spring Boot 中,如果想要配置 Kaptcha 自己提供的 Servlet,方式如下:
@Bean ServletRegistrationBean<HttpServlet>?kaptchaServlet()?{ ????ServletRegistrationBean<HttpServlet>?bean?=?new?ServletRegistrationBean<>(); ????bean.setServlet(new?KaptchaServlet()); ????bean.addUrlMappings("/img"); ????Properties?properties?=?new?Properties(); ????//?是否有邊框?默認(rèn)為true?我們可以自己設(shè)置yes,no ????properties.setProperty(KAPTCHA_BORDER,?"yes"); ????//?驗(yàn)證碼文本字符顏色?默認(rèn)為Color.BLACK ????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR,?"black"); ????//?驗(yàn)證碼圖片寬度?默認(rèn)為200 ????properties.setProperty(KAPTCHA_IMAGE_WIDTH,?"160"); ????//?驗(yàn)證碼圖片高度?默認(rèn)為50 ????properties.setProperty(KAPTCHA_IMAGE_HEIGHT,?"60"); ????//?驗(yàn)證碼文本字符大小?默認(rèn)為40 ????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE,?"38"); ????//?KAPTCHA_SESSION_KEY ????properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY,?"kaptchaCode"); ????//?驗(yàn)證碼文本字符長(zhǎng)度?默認(rèn)為5 ????properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH,?"4"); ????//?驗(yàn)證碼文本字體樣式?默認(rèn)為new?Font("Arial",?1,?fontSize),?new?Font("Courier",?1,?fontSize) ????properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES,?"Arial,Courier"); ????//?圖片樣式?水紋com.google.code.kaptcha.impl.WaterRipple?魚(yú)眼com.google.code.kaptcha.impl.FishEyeGimpy?陰影com.google.code.kaptcha.impl.ShadowGimpy ????properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL,?"com.google.code.kaptcha.impl.ShadowGimpy"); ????Map<String,?String>?map?=?new?HashMap<String,String>((Map)properties); ????bean.setInitParameters(map); ????return?bean; }
項(xiàng)目啟動(dòng)后,直接訪問(wèn) /img
就能看到驗(yàn)證碼圖片,此時(shí)驗(yàn)證碼的文本也會(huì)自動(dòng)存入到 session 中。當(dāng)用戶登錄的時(shí)候,通過(guò) session.getAttribute("kaptchaCode")
就可以獲取到驗(yàn)證碼的文本內(nèi)容。
然而很多時(shí)候,驗(yàn)證碼接口返回的內(nèi)容都是比較豐富的,可能不僅僅是圖片,還有其他信息。所以我們直接配一個(gè) Servlet 并不能滿足我們的要求,只能自己寫(xiě)驗(yàn)證碼的接口,自己寫(xiě)的話,就要自己把驗(yàn)證碼圖片存到 session 中去,那么 properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
配置其實(shí)就沒(méi)用了,可以不用加。
2. 自定義驗(yàn)證碼文本
當(dāng)然,我們也可以自定義驗(yàn)證碼文本,只需要提供一個(gè)驗(yàn)證碼文本的實(shí)現(xiàn)類即可,如下:
public?class?KaptchaTextCreator?extends?DefaultTextCreator?{ ????private?static?final?String[]?CNUMBERS?=?"0,1,2,3,4,5,6,7,8,9,10".split(","); ????@Override ????public?String?getText()?{ ????????Integer?result?=?0; ????????Random?random?=?new?Random(); ????????int?x?=?random.nextInt(10); ????????int?y?=?random.nextInt(10); ????????StringBuilder?suChinese?=?new?StringBuilder(); ????????int?randomoperands?=?(int)?Math.round(Math.random()?*?2); ????????if?(randomoperands?==?0)?{ ????????????result?=?x?*?y; ????????????suChinese.append(CNUMBERS[x]); ????????????suChinese.append("*"); ????????????suChinese.append(CNUMBERS[y]); ????????}?else?if?(randomoperands?==?1)?{ ????????????if?(!(x?==?0)?&&?y?%?x?==?0)?{ ????????????????result?=?y?/?x; ????????????????suChinese.append(CNUMBERS[y]); ????????????????suChinese.append("/"); ????????????????suChinese.append(CNUMBERS[x]); ????????????}?else?{ ????????????????result?=?x?+?y; ????????????????suChinese.append(CNUMBERS[x]); ????????????????suChinese.append("+"); ????????????????suChinese.append(CNUMBERS[y]); ????????????} ????????}?else?if?(randomoperands?==?2)?{ ????????????if?(x?>=?y)?{ ????????????????result?=?x?-?y; ????????????????suChinese.append(CNUMBERS[x]); ????????????????suChinese.append("-"); ????????????????suChinese.append(CNUMBERS[y]); ????????????}?else?{ ????????????????result?=?y?-?x; ????????????????suChinese.append(CNUMBERS[y]); ????????????????suChinese.append("-"); ????????????????suChinese.append(CNUMBERS[x]); ????????????} ????????}?else?{ ????????????result?=?x?+?y; ????????????suChinese.append(CNUMBERS[x]); ????????????suChinese.append("+"); ????????????suChinese.append(CNUMBERS[y]); ????????} ????????suChinese.append("=?@"?+?result); ????????return?suChinese.toString(); ????} }
這段代碼并不難理解,生成的驗(yàn)證碼文本類似于 1+1=?@2
這樣的字符串。
將來(lái)以@為分界線,將@前面的字符串內(nèi)容繪制到圖片上,@后面的內(nèi)容存到 session 中,和用戶上傳的內(nèi)容進(jìn)行比較即可。
當(dāng)然,我們還需要在配置驗(yàn)證碼的時(shí)候添加如下屬性,以修改驗(yàn)證碼文本的提供類:
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL,?"org.javaboy.tienchin.framework.config.KaptchaTextCreator");
配置完成后,將來(lái)在接口中直接使用這個(gè)驗(yàn)證碼即可,用的時(shí)候注意將生成的驗(yàn)證碼文本拆分后處理,一部分用來(lái)繪圖,一部分用來(lái)存到 session 中。
完整的代碼,小伙伴們可以參考TienChin項(xiàng)目
以上就是SpringBoot+kaptcha實(shí)現(xiàn)驗(yàn)證碼花式玩法詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot kaptcha驗(yàn)證碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot+kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能詳解
- SpringBoot整合kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能
- Springboot?+redis+谷歌開(kāi)源Kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能
- SpringBoot集成Kaptcha驗(yàn)證碼的詳細(xì)過(guò)程
- SpringBoot使用Kaptcha實(shí)現(xiàn)驗(yàn)證碼的生成與驗(yàn)證功能
- Google Kaptcha 框架實(shí)現(xiàn)登錄驗(yàn)證碼功能(SSM 和 SpringBoot)
- springboot整合kaptcha驗(yàn)證碼的示例代碼
- SpringBoot 集成Kaptcha實(shí)現(xiàn)驗(yàn)證碼功能實(shí)例詳解
- SpringBoot整合Kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼加減乘除功能
相關(guān)文章
Java啟動(dòng)Tomcat的實(shí)現(xiàn)步驟
本文主要介紹了Java啟動(dòng)Tomcat的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05淺談?dòng)胘ava實(shí)現(xiàn)事件驅(qū)動(dòng)機(jī)制
這篇文章主要介紹了淺談?dòng)胘ava實(shí)現(xiàn)事件驅(qū)動(dòng)機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09spring入門(mén)教程之bean的繼承與自動(dòng)裝配詳解
眾所周知Spring里面的bean就類似是定義的一個(gè)組件,而這個(gè)組件的作用就是實(shí)現(xiàn)某個(gè)功能的,下面這篇文章主要給大家介紹了關(guān)于spring入門(mén)教程之bean繼承與自動(dòng)裝配的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11SpringCloud分布式項(xiàng)目下feign的使用示例詳解
這篇文章主要介紹了SpringCloud分布式項(xiàng)目下feign的使用,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07在CentOS系統(tǒng)上安裝Java?JDK?8簡(jiǎn)單步驟
最近購(gòu)買(mǎi)一臺(tái)新的云服務(wù)器,用于開(kāi)發(fā)學(xué)習(xí)使用,因此需要安裝很多的組件,下面這篇文章主要給大家介紹了關(guān)于在CentOS系統(tǒng)上安裝Java?JDK8的簡(jiǎn)單步驟,需要的朋友可以參考下2023-12-12Netty + ZooKeeper 實(shí)現(xiàn)簡(jiǎn)單的服務(wù)注冊(cè)與發(fā)現(xiàn)
服務(wù)注冊(cè)和發(fā)現(xiàn)一直是分布式的核心組件。本文介紹了借助 ZooKeeper 做注冊(cè)中心,如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的服務(wù)注冊(cè)和發(fā)現(xiàn)。,需要的朋友可以參考下2019-06-06spring security 5.x實(shí)現(xiàn)兼容多種密碼的加密方式
spring security針對(duì)該功能有兩種實(shí)現(xiàn)方式,一種是簡(jiǎn)單的使用加密來(lái)保證基于 cookie 的 token 的安全,另一種是通過(guò)數(shù)據(jù)庫(kù)或其它持久化存儲(chǔ)機(jī)制來(lái)保存生成的 token。這篇文章主要給大家介紹了關(guān)于spring security 5.x實(shí)現(xiàn)兼容多種密碼的加密方式,需要的朋友可以參考下。2018-01-01JAVA中 redisTemplate 和 jedis的配合使用操作
這篇文章主要介紹了JAVA中 redisTemplate 和 jedis的配合使用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12