驗(yàn)證碼的作用是防止惡意破解密碼、刷票咽安、論壇灌水伴网、刷頁(yè)等。
如下是一個(gè)實(shí)際例子:
而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):
反正我用起來(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ǎ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)證碼的功能完成了度陆,順便附上截圖:
本篇筆記就到這里,如果稍微幫到你了記得點(diǎn)個(gè)喜歡點(diǎn)個(gè)關(guān)注献幔。也祝大家工作順順利利懂傀,生活愉快!