java-Kaptcha生成驗(yàn)證碼圖片(五分鐘學(xué)會(huì))

驗(yàn)證碼的作用是防止惡意破解密碼、刷票咽安、論壇灌水伴网、刷頁(yè)等。
如下是一個(gè)實(shí)際例子:


image.png

而Kaptcha則是生成這樣的驗(yàn)證碼圖片的一個(gè)功能強(qiáng)大的工具包妆棒。
然后開(kāi)始說(shuō)這個(gè)Kaptcha要怎么使用澡腾。

導(dǎo)包

<dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>kaptcha</artifactId>
    <version>0.0.9</version>
</dependency>

添加配置

package io.renren.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;


/**
 * 生成驗(yàn)證碼配置
 *
 * @author Mark sunlightcs@gmail.com
 */
@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha producer() {
        Properties properties = new Properties();
        properties.put("kaptcha.border", "no");
        properties.put("kaptcha.textproducer.font.color", "black");
        properties.put("kaptcha.textproducer.char.space", "6");
        properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋體,楷體,微軟雅黑");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

然后上面的幾個(gè)配置自己看著寫(xiě)。這個(gè)kaptcha有多種配置可以改的糕珊,我貼出來(lái):


kaptcha可選參數(shù)

可選參數(shù)2

反正我用起來(lái)也沒(méi)那么麻煩动分,其實(shí)默認(rèn)配置差不多就滿足了,自己看心意調(diào)吧放接。

在接口中使用

以上兩步配置就完了刺啦,接下來(lái)該使用了。
其實(shí)就是把它配置成一個(gè)可以前端訪問(wèn)的接口了纠脾。

存session中

    @Autowired
    private Producer producer;
    
    @GetMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response,HttpServletRequest request) throws ServletException,IOException{
        response.setHeader("Cache-Control", "no-store,no-cache");
        response.setContentType("image/jpeg");
        //生成文字驗(yàn)證碼
        String text=producer.createText();
        //生成圖片驗(yàn)證碼
        BufferedImage image=producer.createImage(text);
        //保存驗(yàn)證碼到session
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        ServletOutputStream out=response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        //用到IO工具包控制開(kāi)關(guān)
        IOUtils.closeQuietly(out);
        
    }

存數(shù)據(jù)庫(kù)

存session就不多說(shuō)了玛瘸,但是我使用的時(shí)候是存數(shù)據(jù)庫(kù)的,個(gè)人感覺(jué)存數(shù)據(jù)庫(kù)可以靈活設(shè)置過(guò)期時(shí)間苟蹈。(好吧糊渊,我承認(rèn)這個(gè)做法是當(dāng)時(shí)沒(méi)想到session)。反正現(xiàn)在是實(shí)現(xiàn)了慧脱,所以也記錄下來(lái)吧渺绒。
因?yàn)榇鏀?shù)據(jù)庫(kù)所以肯定要先建表:


表結(jié)構(gòu)

如圖,很簡(jiǎn)單的表結(jié)構(gòu):uuid是主鍵菱鸥,code是驗(yàn)證碼宗兼。expire_time是過(guò)期時(shí)間。
然后每次生成驗(yàn)證碼氮采,需要一個(gè)參數(shù)(說(shuō)是uuid其實(shí)用的時(shí)候就是一個(gè)id的作用)殷绍。會(huì)將這個(gè)uuid當(dāng)做表的主鍵,然后code和過(guò)期時(shí)間一起存到數(shù)據(jù)庫(kù)鹊漠。
在登錄的時(shí)候先做校驗(yàn)主到,判斷這個(gè)uuid的code和輸入的驗(yàn)證碼是否一樣,是的話驗(yàn)證成功躯概,并且刪除這條記錄登钥。不是的話返回驗(yàn)證碼錯(cuò)誤。
大概邏輯就是這樣娶靡,我一步步貼代碼:
這個(gè)是將驗(yàn)證碼保存到數(shù)據(jù)庫(kù)和校驗(yàn)驗(yàn)證碼的兩個(gè)方法

    @Autowired
    private Producer producer;
    
    /**
     * 生成驗(yàn)證碼并且將這條記錄保存到數(shù)據(jù)庫(kù)
     */
    @Override
    public BufferedImage getCaptcha(String uuid) {
        if(StringUtils.isBlank(uuid)){
            throw new RRException("uuid不能為空");
        }
        //生成文字驗(yàn)證碼
        String code = producer.createText();
        //這里是生成實(shí)體牧牢,然后存入數(shù)據(jù)庫(kù),看邏輯就行,別原封不動(dòng)用代碼
        SysCaptchaEntity captchaEntity = new SysCaptchaEntity();
        captchaEntity.setUuid(uuid);
        captchaEntity.setCode(code);
        //3分鐘后過(guò)期.這個(gè)用到了自己封裝的日期處理方法
        captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 3));
        this.save(captchaEntity);
        return producer.createImage(code);
    }
    
    
    /**
     * 驗(yàn)證驗(yàn)證碼是否正確
     */
    @Override
    public boolean validate(String uuid, String code) {
        SysCaptchaEntity captchaEntity = this.getOne(new QueryWrapper<SysCaptchaEntity>().eq("uuid", uuid));
        if(captchaEntity == null){
            return false;
        }

        //刪除驗(yàn)證碼
        this.removeById(uuid);

        if(captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){
            return true;
        }

        return false;
    }

這個(gè)是正式調(diào)用生成驗(yàn)證碼的方法:

    /**
     * 驗(yàn)證碼
     */
    @ApiOperation("獲取驗(yàn)證碼")
    @RequestMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response, @ApiParam(name="uuid",value="隨機(jī)字符串") String uuid)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //獲取圖片驗(yàn)證碼
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

這個(gè)是在登錄的時(shí)候驗(yàn)證驗(yàn)證碼的兩行代碼:

boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
        if(!captcha){
            return R.error("驗(yàn)證碼不正確");
        }

至此结执,這個(gè)生成驗(yàn)證碼的功能完成了度陆,順便附上截圖:


postman自測(cè)

網(wǎng)頁(yè)測(cè)試

本篇筆記就到這里,如果稍微幫到你了記得點(diǎn)個(gè)喜歡點(diǎn)個(gè)關(guān)注献幔。也祝大家工作順順利利懂傀,生活愉快!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜡感,一起剝皮案震驚了整個(gè)濱河市蹬蚁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郑兴,老刑警劉巖犀斋,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異情连,居然都是意外死亡叽粹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)却舀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)虫几,“玉大人,你說(shuō)我怎么就攤上這事挽拔×玖常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵螃诅,是天一觀的道長(zhǎng)啡氢。 經(jīng)常有香客問(wèn)我,道長(zhǎng)术裸,這世上最難降的妖魔是什么倘是? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮袭艺,結(jié)果婚禮上搀崭,老公的妹妹穿的比我還像新娘。我一直安慰自己匹表,他們只是感情好门坷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布宣鄙。 她就那樣靜靜地躺著袍镀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冻晤。 梳的紋絲不亂的頭發(fā)上苇羡,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音鼻弧,去河邊找鬼设江。 笑死锦茁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叉存。 我是一名探鬼主播码俩,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼歼捏!你這毒婦竟也來(lái)了稿存?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瞳秽,失蹤者是張志新(化名)和其女友劉穎瓣履,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體练俐,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袖迎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腺晾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片燕锥。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丘喻,靈堂內(nèi)的尸體忽然破棺而出脯宿,到底是詐尸還是另有隱情,我是刑警寧澤泉粉,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布连霉,位于F島的核電站,受9級(jí)特大地震影響嗡靡,放射性物質(zhì)發(fā)生泄漏跺撼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一歉井、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哈误,春花似錦哩至、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至重荠,卻和暖如春箭阶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工仇参, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘹叫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓诈乒,卻偏偏與公主長(zhǎng)得像罩扇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怕磨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • feisky云計(jì)算暮蹂、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,815評(píng)論 0 5
  • 1.JVM 堆內(nèi)存和非堆內(nèi)存 堆和非堆內(nèi)存按照官方的說(shuō)法:“Java 虛擬機(jī)具有一個(gè)堆(Heap),堆是運(yùn)行時(shí)數(shù)據(jù)...
    yanzhu728閱讀 902評(píng)論 0 0
  • 這幾天不知怎么有點(diǎn)倦怠了癌压,因?yàn)橹坝型A艘惶煅鲂海驗(yàn)槭謾C(jī)忘在外面了。 我最近生活的確有些改變滩届。本來(lái)國(guó)慶準(zhǔn)備出去學(xué)習(xí)集侯,...
    何偀閱讀 209評(píng)論 1 0
  • 身體痛了,我們能夠感知到帜消。 可是心疼了棠枉,你能感受到嗎? 你真的了解自己當(dāng)下的情緒嗎泡挺?...
    胖粽子皮閱讀 665評(píng)論 3 7
  • 1辈讶、電影行業(yè)背景及前景: 按照目前院線電影上映的票房情況來(lái)預(yù)測(cè),您投資10萬(wàn)娄猫,這四種收益都到手您可以直接在二線城市...
    銀狐影視談電影世界閱讀 5,796評(píng)論 0 0