图片验证码的实现以及校验验证码
关于图片验证码的时候,我们用到地方有很多,我们这次做的图片验证码是我们通过代码生成的图片,然后将其加密为Base64编码。
还是之前的一样,我们要线理一下思路,对于验证码,我们需要怎么做
最开始先导入图片验证码的依赖包
<!-- 图片验证码依赖 --><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>
1、我们需要设置图片验证码的样式,就是显示给我们看的样式,我们需要自己配置
配置文件内存
captchaParameter.properties
#=========================== project Configuration =========================
project.valid-duration=300000
#=========================== captcha Configuration=========================
#\u8FB9\u6846\u989C\u8272
captcha.border.color=blue
#\u8FB9\u6846\u5BBD\u5EA6
captcha.border.thickness=1
#\u56FE\u7247\u5BBD\u5EA6
captcha.image.width=200
#\u56FE\u7247\u9AD8\u5EA6
captcha.image.height=60
#\u56FE\u7247\u5B9E\u73B0\u7C7B
captcha.producer.impl=com.google.code.kaptcha.impl.DefaultKaptcha
#\u9A8C\u8BC1\u7801\u503C
captcha.textproducer.char.string=3456789ABCEFJKMPQRTUVXY
#\u9A8C\u8BC1\u7801\u957F\u5EA6
captcha.textproducer.char.length=4
#\u6587\u5B57\u95F4\u9694
captcha.textproducer.char.space=18
#\u5B57\u4F53
captcha.textproducer.font.name=Arial,Courier
#\u5B57\u4F53\u5927\u5C0F
captcha.textproducer.font.size=30
#\u5B57\u4F53\u989C\u8272
captcha.textproducer.font.color=black
#\u5E72\u6270\u7EBF\u5B9E\u73B0\u7C7B
captcha.nosie.impl=com.google.code.kaptcha.impl.NoNoise
#\u5E72\u6270\u989C\u8272
captcha.nosie.color=lightGray
#\u56FE\u7247\u6837\u5F0F
captcha.obscurificator.impl=com.google.code.kaptcha.impl.ShadowGimpy
#\u80CC\u666F\u5B9E\u73B0\u7C7B
captcha.background.impl=com.google.code.kaptcha.impl.DefaultBackground
#\u80CC\u666F\u6E10\u53D8\u5F00\u59CB
captcha.background.clear.from=lightGray
#\u80CC\u666F\u6E10\u53D8\u7ED3\u675F
captcha.background.clear.to=white
#\u6587\u5B57\u6E32\u67D3\u5668
captcha.word=com.google.code.kaptcha.text.impl.DefaultWordRenderer
#session key
captcha.session.key=KAPTCHA_SESSION_KEY
#session date
captcha.session.date=KAPTCHA_SESSION_DATE
1.1、创建配置实体类,获取到配置文件中的属性
CaptchaParameterConfig
@Data
@Component
@PropertySource(value = {"classpath:captchaParameter.properties"})
public class CaptchaParameterConfig {/*** 验证码有效期*/@Value("${project.valid-duration}")private Integer validDuration;/*** 边框颜色*/@Value("${captcha.border.color}")private String captchaBorderColor;/*** 边框宽度*/@Value("${captcha.border.thickness}")private String captchaBorderThickness;/*** 图片宽度*/@Value("${captcha.image.width}")private String captchaImageWidth;/*** 图片高度*/@Value("${captcha.image.height}")private String captchaImageHeight;/*** 图片实现类*/@Value("${captcha.producer.impl}")private String captchaProducerImpl;/*** 验证码值*/@Value("${captcha.textproducer.char.string}")private String captchaTextProducerCharString;/*** 验证码长度*/@Value("${captcha.textproducer.char.length}")private String captchaTextProducerCharLength;/*** 文字间隔*/@Value("${captcha.textproducer.char.space}")private String captchaTextProducerCharSpace;/*** 字体*/@Value("${captcha.textproducer.font.name}")private String captchaTextProducerFontName;/*** 字体大小*/@Value("${captcha.textproducer.font.size}")private String captchaTextProducerFontSize;/*** 字体颜色*/@Value("${captcha.textproducer.font.color}")private String captchaTextProducerFontColor;/*** 干扰线实现类*/@Value("${captcha.nosie.impl}")private String captchaNosieImpl;/*** 干扰颜色*/@Value("${captcha.nosie.color}")private String captchaNosieColor;/*** 图片样式*/@Value("${captcha.obscurificator.impl}")private String captchaObscurificatorImpl;/*** 背景实现类*/@Value("${captcha.background.impl}")private String captchaBackgroundImpl;/*** 背景渐变开始*/@Value("${captcha.background.clear.from}")private String captchaBackgroundClearFrom;/*** 背景渐变结束*/@Value("${captcha.background.clear.to}")private String captchaBackgroundClearTo;/*** 文字渲染器*/@Value("${captcha.word}")private String captchaWord;/*** session key*/@Value("${captcha.session.key}")private String captchaSessionKey;/*** session date*/@Value("${captcha.session.date}")private String captchaSessionDate;
}
1.2、配置类
@Configuration
public class CaptchaConfig {@Autowiredprivate CaptchaParameterConfig parameterConfig;@Beanpublic DefaultKaptcha producer() {Properties properties = new Properties();//边框properties.put("kaptcha.border", "no");properties.put("kaptcha.border.color", parameterConfig.getCaptchaBorderColor());properties.put("kaptcha.border.thickness", parameterConfig.getCaptchaBorderThickness());//图片properties.put("kaptcha.image.width", parameterConfig.getCaptchaImageWidth());properties.put("kaptcha.image.height", parameterConfig.getCaptchaImageHeight());//图片实现类properties.put("kaptcha.producer.impl", parameterConfig.getCaptchaProducerImpl());//文本properties.put("kaptcha.textproducer.char.space", parameterConfig.getCaptchaTextProducerCharSpace());properties.put("kaptcha.textproducer.char.length", parameterConfig.getCaptchaTextProducerCharLength());properties.put("kaptcha.textproducer.char.string", parameterConfig.getCaptchaTextProducerCharString());properties.put("kaptcha.textproducer.font.name", parameterConfig.getCaptchaTextProducerFontName());properties.put("kaptcha.textproducer.font.size", parameterConfig.getCaptchaTextProducerFontSize());properties.put("kaptcha.textproducer.font.color", parameterConfig.getCaptchaTextProducerFontColor());//干扰properties.put("kaptcha.noise.impl", parameterConfig.getCaptchaNosieImpl());properties.put("kaptcha.noise.color", parameterConfig.getCaptchaNosieColor());//图片样式properties.put("kaptcha.background.impl", parameterConfig.getCaptchaBackgroundImpl());//渐变properties.put("kaptcha.background.clear.from", parameterConfig.getCaptchaBackgroundClearFrom());properties.put("kaptcha.background.clear.to", parameterConfig.getCaptchaBackgroundClearTo());//文字渲染器properties.put("kaptcha.word", parameterConfig.getCaptchaWord());//sessionproperties.put("kaptcha.session.key", parameterConfig.getCaptchaSessionKey());properties.put("kaptcha.session.date", parameterConfig.getCaptchaSessionDate());Config config = new Config(properties);DefaultKaptcha defaultKaptcha = new DefaultKaptcha();defaultKaptcha.setConfig(config);return defaultKaptcha;}
}
我们的图片验证码的样式就设置好了,但是我这边看不到,这个只是前段能看到
其实主要是有一个方法我们需要用DefaultKaptcha类的方法, 我们根据我们设置的验证码样式,可以使用它的**createText()方法,就可以获取到一个随机的验证码,然后在将我们获取到的验证码放如createImage()**这个方法中,我们就可以得到一个图片验证码
2、实体类
我用的是JPA直接创建的表
@Data
@Entity
@Table(name = "picture")
@EntityListeners(AuditingEntityListener.class)//时间标签,写了它,CreatedDate才能起作用
public class PictureValidationCodeDO {/*** 主键*/@Id@GenericGenerator(name = "system-uuid",strategy = "uuid")@GeneratedValue(strategy = GenerationType.AUTO, generator = "system-uuid")@Column(length = 50,name = "id")private String id;/*** 创建时间*/@CreatedDate@Column(nullable = false, updatable = false, name = "create_date" ,columnDefinition = "datetime COMMENT '创建时间'")private Date createDate;/*** 验证码*/@Column(name = "code", columnDefinition = "varchar(50) comment '验证码' ")private String code;}
3、Service接口
public interface PictureValidationCodeService {/*** 生成验证码* @return*/PictureValidationVO generate() throws Exception;/*** 校验验证码* @param checkRequest*/void validate(PictureValidationCheckRequest checkRequest) throws Exception;
}
PictureValidationVO 只是我自己创建的另一个实体类,它只是用来接收数据的一个实体类,我们可以用DO直接当做返回对象,个人习惯
4、ServiceImpl(最重要的一步)
我们传参也一样,我这边也自己写了一个实体类,专门用来传参数
PictureValidationCheckRequest
@Service
@Slf4j
public class PictureValidationCodeServiceImpl implements PictureValidationCodeService {@Autowiredprivate DefaultKaptcha defaultKaptcha;@Autowiredprivate PictureValidationCodeRepository pictureValidationCodeRepository;@Autowiredprivate CaptchaParameterConfig parameterConfig;/*** 生成验证码* @return*/@Overridepublic PictureValidationVO generate() throws Exception {log.info("生成图片验证码-service-开始");//通过DefaultKaptcha获得随机验证码String text = defaultKaptcha.createText();//生成图片加密后Base64字符串String imgBase64String = getImgBase64String(text);//添加验证码,保存到数据库中PictureValidationCodeDO pictureValidationCodeDO = savePictureValidationCode(text);//构造图片验证码(id,code)PictureValidationVO pictureValidationVO = new PictureValidationVO(pictureValidationCodeDO.getId(), imgBase64String);log.info("生成图片验证码-service-结束[id:{}]", pictureValidationVO.getId());return pictureValidationVO;}/*** 校验验证码* @param checkRequest*/@Overridepublic void validate(PictureValidationCheckRequest checkRequest) throws Exception {log.debug("校验图片验证码-service-开始[checkRequest:{}]", checkRequest);//根据id查询验证码Optional<PictureValidationCodeDO> validationCodeDO = pictureValidationCodeRepository.findById(checkRequest.getId());//判断验证码是否存在if (!validationCodeDO.isPresent()){log.info("校验验证码失败,验证码不存在[checkRequest:{}]", checkRequest);throw new Exception("验证码不存在");}PictureValidationCodeDO pictureValidationCodeDO = validationCodeDO.get();//校验验证码是否过期if (System.currentTimeMillis() - pictureValidationCodeDO.getCreateDate().getTime() > parameterConfig.getValidDuration()) {log.info("校验验证码失败,验证码已过期[checkRequest:{}]", checkRequest);throw new Exception("验证码已过期");}//判断输入的验证码是否正确if(!pictureValidationCodeDO.getCode().equals(checkRequest.getCode())){log.info("验证码错误[checkRequest:{}]", checkRequest);}log.info("校验图片验证码-service-结束");}/*** 添加验证码(保存到数据库中)* @param code* @return*/private PictureValidationCodeDO savePictureValidationCode(String code){PictureValidationCodeDO pictureValidationCodeDO = new PictureValidationCodeDO();pictureValidationCodeDO.setCode(code);PictureValidationCodeDO save = pictureValidationCodeRepository.save(pictureValidationCodeDO);return save;}/*** 生成图片加密后Base64字符串** @param code* @return Base64字符串*/private String getImgBase64String(String code) throws Exception {//将我们生成的随机验证码转换为图片//将验证码图片转换成字节流BufferedImage image = defaultKaptcha.createImage(code);//获取二进制输出流ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();try {ImageIO.write(image, "jpg", jpegOutputStream);} catch (IOException e) {e.printStackTrace();throw new Exception("验证码图片转换成字节流失败");}//返回Base64字符串return Base64.encodeBase64String(jpegOutputStream.toByteArray());
}}
5、然后就是我们的Controller类
@RestController
@Slf4j
@Api(tags = "图片验证码管理", description = "图片验证码管理")
public class PictureValidationCodeController {@Autowiredprivate PictureValidationCodeService pictureValidationCodeService;/*** 生成图片验证码* @return*/@ApiOperation("生成图片验证码")@GetMapping("/generate")public PictureValidationVO generate() throws Exception {log.info("生成图片验证码开始" );PictureValidationVO pictureValidationVO = pictureValidationCodeService.generate();log.info("生成验证码成功");return pictureValidationVO;}
/*** 校验验证码* @param checkRequest* @throws Exception*/@ApiOperation("校验验证码")@PostMapping("/validate")public void validate(PictureValidationCheckRequest checkRequest) throws Exception {log.info("校验验证码开始");pictureValidationCodeService.validate(checkRequest);log.info("校验验证码成功");}
}
然后我们就可以直接测试一下
这就生成成功了
校验也是一样的,因为我是直接存到数据库的,所以我们直接去数据库看
这就考验看到,我们的验证码id,以及他们的值,我们在前端看到的话,就是一个图片,和平时的验证码一样
图片验证码的实现以及校验验证码相关推荐
- 魔方APP项目-07-客户端提交登录信息、在APICloud中集成防水墙验证码,前端获取显示并校验验证码、服务端校验验证码、保存用户登录状态,APICloud提供的数据存储、客户端保存用户登陆数据
用户登录 一.客户端提交登录信息 html/login.html,代码: <!DOCTYPE html> <html> <head><title>登录& ...
- java 生成校验验证码_java 验证码生成与校验
java绘图相关类 验证码工具类 package dt2008.util; import javax.imageio.ImageIO; import javax.servlet.http.HttpSe ...
- 使用ThinkPHP实现生成/校验验证码功能
首先了解父类Verity.class.php(ThinkPHP/Library/Think/Verity.class.php)中的一些函数 1:check() 校验验证码是否正确 2:entry()输 ...
- java 图形校验_java图形验证码生成工具类 web页面校验验证码
java图形验证码生成工具类 web页面校验验证码 发布于 2020-7-14| 复制链接 摘记: 最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善.验证码生成器: ```java i ...
- java 生成校验验证码_java生成验证码并进行验证
一实现思路使用BufferedImage用于在内存中存储生成的验证码图片使用Graphics来进行验证码图片的绘制,并将绘制在图片上的验证码存放到session中用于后续验证 最后通过ImageIO将 ...
- 在JSP中动态生成随机验证码,登录时后台校验验证码,以及如何避免同一个验证码被重复提交爆破密码...
只需几步就可以生成动态随机的验证码,最终效果如下图: 一 前台显示页面login.jsp 其中验证码显示的是一张图片,链接指向的是生成验证码的servlet,同时点击图片后触发changeImg()这 ...
- javaweb登录界面验证码自动生成,点击重新生成验证码,验证码与输入框的校验
当进入登录界面时,验证码图片自动生成,验证码图片颜色随机,字母颜色随机,该代码只是随机生成小写英文字母,没有设置大写字母和数字 点击验证码图片重新生成验证码 验证码输入错误时,提示出来 验证码输入正确 ...
- 登录页面自动刷新验证码,并校验输入验证码和后台生成的验证码是否一致
登录jsp页面 <%@ page language="java" contentType="text/html; charset=UTF-8"pageEn ...
- python 识别登陆验证码图片(完整代码)_python 识别登录验证码图片功能的实现代码(完整代码)...
在编写自动化测试用例的时候,每次登录都需要输入验证码,后来想把让python自己识别图片里的验证码,不需要自己手动登陆,所以查了一下识别功能怎么实现,做一下笔记. 首选导入一些用到的库,re.Imag ...
- 校验验证码 实现登录验证
验证码处理 方式 1.手动处理 2.云打码平台自动识别验证码 实现流程:-1.对携带验证码的页面数据进行抓取-2.可以将验证码图片进行解析,验证码图片下载到本地-3.将验证码图片交给第三方进行识别,返 ...
最新文章
- 【Android 热修复】热修复原理 ( 合并两个 Element[] dexElements | 自定义 Application 加载 Dex 设置 | 源码资源 )
- 世界 Web 2.0 网站评奖揭晓
- linux 退后根目录,linux下半部与退后执行的工作
- Java基础面试题与答案
- LeetCode 454. 4Sum II
- python 高性能http服务器_Python高性能HTTP客户端
- vue踩坑--TypeError: __WEBPACK_IMPORTED_MODULE_1_vuex__.a.store is not a constructor
- 二级c语言2013年真题,2013年3月全国计算机二级c语言真题
- 单片机的现状即发展前景
- 编译原理(第3版)——引论
- cmd 、java获取硬盘的序列号(serialnumber)物理地址 和磁盘ID逻辑地址
- Ubuntu20.04安装mujoco
- 炉石传说android手机版本,炉石传说安卓手机版官方apk
- Java内存泄漏检测工具 JRockit Memory Leak Detector
- Mex-hdu4747(DP)
- 腾讯云发布智慧员工管理方案,支持组织360度协作
- js日期格式化(Date format)
- windows10 录音机内录、外录、内外混合录的方法
- idea搜不到子目录下的配置怎么解决
- Jquery文本域(textarea)改变事件
热门文章
- 利用IE登陆windows 2003 的终端服务器
- 安装服务器系统提示加载驱动程序,启动sqlserver服务时,总是出现“系统错误(126),指定驱动程序无法加载,...
- 视频教程-2020年软考网络工程师基础知识软考视频教程-软考
- cs 5 下载地址 、视频教程、安装教程
- python aes new_python--AES加密
- eds能谱图分析实例_电子产品质量的提升,离不开这些失效分析!
- 【钛坦白】清华大学李建:深度学习在时空大数据分析中的应用(转载)
- 威金杀虫剂作者农夫和威金病毒制造者的聊天记录
- android adb 命令启动,如何从adb shell启动和停止android服务?
- eclipse工具栏全部隐藏