马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
一 实现思绪
二 代码实现
三 代码汇总
如今的登录都必要输入验证码用来检测是否是真人登录,以是验证码功能在如今好坏常广泛的,那么接下来我们就基于springboot来实现验证码功能。
一 实现思绪
本日我们先容的是两种主流的验证码,一种就是上图所示的必要举行盘算的验证码,别的一种就是不必要盘算,直接输入的验证码。
1.如果验证码的范例是一个盘算范例验证码
- * 那么我们就需要分析一下:
- * 比如一个计算类型的验证码:1+2=?
- * 那么我们到时候应该填入的验证码的答案是:3
- * 所以这个验证码它包含了两个部分,一个是"1+2=?" 另外一个是"3"
- * 其实生成这个计算问题是我们自己来实现的,我们的工具类已经封装好了计算提,比如:“1+2=3”
- * 所以我们现在要做的主要有三步:
- * 1.得到这个算式后,将算是“1+2=3”分割成两个部分,“1+2=?” 和 “3”
- * 2.然后我们需要把它们存储到缓存中去,前面可以当作key,后面可以当作value,然后进行验证答案的正确性
- * 3.最后,我们需要把“1+2=?”制作成一个图片返回给前端,用于展示给用户,
复制代码 2.如果验证码的范例是一个寻常的图形验证码
那么我们不要分为表达式和答案两个部门,我们只必要把天生的这个图形直接存入缓存中去就可以了。
但是由于我们这两种范例是在同一个类中举行判断的,以是最好还是用两个变量来吸取。
上面这两中范例的验证码判断完成之后,不管是那种范例,末了都必要把数据存到缓存中,而且都会天生一个Base64编码的一个图片,我们只必要返回这个图片即可,还必要一个uuid,由于这个是用来作为key的唯一标识。
二 代码实现
开始代码之前,先先容一下我注入的几个bean:
- @Autowired
- private ISysConfigService configService ; //判断是否开启验证码
- @Autowired
- private FeiSiConfig feiSiConfig ; //配置信息
- @Autowired
- private KaptchaTextCreator kaptchaTextCreator ; //随机生成验证码表达式
- @Autowired
- private RedisCache redisCache ; //存储数据到缓存
- @Resource(name = "captchaProducer")
- private Producer captchaProducer; //生成普通类型验证码图片
- @Resource(name="captchaProducerMath")
- private Producer captchaProducerMath; //生成计算类型验证码图片
复制代码 ① 先判断有没有开启验证码功能。
我们有一个网页功能的数据库表,内里可以选择是否开启验证码功能,而且在类加载的时间,我们就已经利用 @PostConstruct(标记在方法上, 当这个bean创建完成,自动实验这个注解标记方法,要求这个方法无参 类似 init-method设置) 注解将数据库的数据缓存在了redis内里。
以是我们可以判断先判断有没有开启验证码功能:
- // 先要判断一下是否开启了验证码功能,如果没有开启,则不需要进行生成验证码的操作了
- boolean captchaEnabled = configService.selectCaptchaEnabled();
- if (!captchaEnabled){
- return ajaxResult.put("captchaOnOff",captchaEnabled) ; //返回没有开启验证码信息给前端
- }
复制代码- configService这个类就是我们用来初始化缓存数据的,这个类代码如下:
复制代码- package com.fs.system.service.ipml;
- import cn.hutool.core.convert.Convert;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.fs.common.constant.CacheConstants;
- import com.fs.common.core.pojo.SysConfig;
- import com.fs.common.util.RedisCache;
- import com.fs.common.util.StringUtils;
- import com.fs.system.mapper.SysConfigMapper;
- import com.fs.system.service.ISysConfigService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import javax.annotation.PostConstruct;
- import java.util.List;
- import java.util.Objects;
- @Service
- public class SysConfigServiceImpl implements ISysConfigService {
- @Autowired
- private SysConfigMapper sysConfigMapper;
- @Autowired
- private RedisCache redisCache;
- @PostConstruct //标记在方法上, 当这个bean创建完成,自动执行这个注解标记方法,要求这个方法无参 类似 init-method配置
- public void init(){
- loadingConfigCache();
- }
- // 初始化数据,当系统加载的时候,把数据存入到缓存中去
- @Override
- public void loadingConfigCache() {
- System.out.println("初始化数据...");
- //查询数据库
- List<SysConfig> sysConfigs = sysConfigMapper.selectList(null);
- //保存到redis缓存中
- sysConfigs.forEach((sysConfig)->{
- redisCache.setCacheObject(getCacheKey(sysConfig.getConfigKey()),sysConfig.getConfigValue());
- });
- }
- /**
- * 构建参数配置表的redis的key
- * @param configKey
- * @return
- */
- // 获取redis缓存中的key
- private String getCacheKey(String configKey){
- return CacheConstants.SYS_CONFIG_KEY+configKey;
- }
- // 判断账号的验证码是否以及开启
- @Override
- public boolean selectCaptchaEnabled() {
- String cacheObject = redisCache.getCacheObject("sys.account.captchaOnOff");
- if (StrUtil.isBlank(cacheObject)){
- // 如果查询出来的是空,则说明该账号是第一次登录,则默认开启验证码
- return true ;
- }
- // 如果不是空,那么查询到的数据不是true就是false,但是存到数据库的并不是Boolean类型而是String类型,
- // 所以我们借用工具直接把字符串转成对应的Boolean类型
- return Convert.toBool(cacheObject) ;
- }
- // 根据账号的key获取缓存中的value
- @Override
- public String selectConfigByKey(String configKey) {
- // 1. 如果从redis中得到了数据,那么直接返回
- String cacheObject = redisCache.getCacheObject(getCacheKey(configKey));
- // 我们需要返回的是一个String类型,所以需要用工具包转为String类型
- String toStr = Convert.toStr(cacheObject);
- if (StrUtil.isNotBlank(toStr)){
- return toStr ;
- }
- // 2.如果没有得到数据,那么我们需要从sys_config数据库表中查询数据,同时把查询到的数据存入缓存中
- LambdaQueryWrapper<SysConfig> queryWrapper=new LambdaQueryWrapper<>();
- queryWrapper.eq(SysConfig::getConfigKey,configKey);
- SysConfig sysConfig = sysConfigMapper.selectOne(queryWrapper);
- // 如果查到有数据,就存入redis并且返回
- if(Objects.nonNull(sysConfig)){ //这里判空的方法不能继续和上面一样,因为sysConfig并不是字符串类型,而是一个对象
- // 获取到值
- String configValue = sysConfig.getConfigValue();
- redisCache.setCacheObject(getCacheKey(configKey),configValue);
- return configValue;
- }
- // 否则没有查到数据,则说明没有信息
- return null ;
- }
- }
复制代码
在举行正式写逻辑代码之前,我们必要引入几个变量。
按照我们上面分析的,如果是一个盘算范例的验证码,那么我们一个必要四个变量:
一个变量是表达式的前半部门,一个变量是表达式的答案,
一个变量是用于存储天生的验证码图片的Base64编码,
末了一个就是验证码数据存储在redis作为唯一标识key的uuid
- BufferedImage image = null ;//图片
- String expression ; //表达式部分
- String answer ; //答案部分
- String uuid = UUID.randomUUID().toString();; //uuid
复制代码
② 判断开启后,我们接下来必要判断利用的是哪一种验证码,详细利用哪一种是我们自己设置好的,我们规定math是盘算范例的验证码,char是寻常验证码。
- /**
- * 至于这个captchaType的值是根据配置文件设置的,因为这个FeisiConfig是一个配置类
- * 它加了‘@ConfigurationProperties(prefix = "fs")’这个注解,
- * 而配置文件规定math是计算类型验证码,char是图形类型验证码
- */
- String captchaType = feiSiConfig.getCaptchaType();
复制代码 </ |