本文采用ehcache 的方式校验验证码真伪,ehcache不需要安装环境(类似于redis、memcached这种本地或者服务器上的环境)很方便。思路是将获取到的验证码发送给用户,并且缓存到服务器,记录用户ID以及对应的验证码,设置失效时间为五分钟。
1、pom.xml 中添加依赖
<!--开启 cache 缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- ehcache缓存 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
</dependency>
2、启动项加入@EnableCaching开启事务
@SpringBootApplication
@EnableScheduling
@ServletComponentScan
@EnableCaching
public class MipIntelligenceApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MipIntelligenceApplication.class);
app.addListeners(new ApplicationPidFileWriter("application.pid"));
app.run(args);
}
}
3、在resource目录下添加ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--
磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存
path:指定在硬盘上存储对象的路径
-->
<diskStore path="/Users/xxxxx/test/ehcache" /><!--这个目录需要改成你本地目录ehcache目录可以没有其他的需要必须存在-->
<!--
defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
eternal:代表对象是否永不过期
overflowToDisk:当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
-->
<defaultCache
maxElementsInMemory="1"
eternal="false"
overflowToDisk="true"/>
<!--
maxElementsInMemory设置成1,overflowToDisk设置成true,只要有一个缓存元素,就直接存到硬盘上去
eternal设置成true,代表对象永久有效
maxElementsOnDisk设置成0 表示硬盘中最大缓存对象数无限大
diskPersistent设置成true表示缓存虚拟机重启期数据
-->
<cache
name="verifyCode"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="300"
overflowToDisk="true"
maxElementsOnDisk="1"
diskPersistent="true"/>
</ehcache>
4、在properties配置文件中加入ehcache.xml 关联 ,放到最下边就可以了
spring.cache.ehcache.config=classpath:ehcache.xml
5、业务逻辑
service 层代码
@CachePut(value = "verifyCode",key = "#userId")//value是配置文件ehcache.xml中的cache的名字,为每个人缓存验证码
public String saveVerifyCode(Long userId,String v) {
logger.info("create validation code----");
return v;
}
@Cacheable(value = "verifyCode", key="#userId")//Cache是发生在verifyCode上的通过人的ID获取对应的验证码
public String findCodeById(Long userId) {
logger.info("findCodeById ----if this message has been printed, the validation code has expired");
return null;//这个地方置空;不写值
}
controller层业务代码
/**
* 获取验证码
* @param tel
* @return
*/
@RequestMapping(value = "/createVerifyCode",method = {RequestMethod.POST,RequestMethod.GET})
public OperateResultVo createVerifyCode(String tel){
OperateResultVo vo = new OperateResultVo();
if (StringUtils.isEmpty(tel)) {
vo.setSuccess(false);
vo.setMsg("请填写登录账号电话号码");
return vo;
}
User user = userService.findByTelAndRoleActive(tel,Long.valueOf(38),Long.valueOf(37));//查寻你们自己的user表,通过电话查询用户信息就可以了
if(user == null) {
vo.setSuccess(false);
vo.setMsg("该账号不存在或未激活");
return vo;
}
try {
Long id = user.getId();
String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);//随机数六位验证码
MoblieMessageUtil.verifyCodeChangPw(tel, verifyCode);//这个是阿里云短信结合其他博主写的方法发送短信就可以了,网上很多不详细介绍了
String code = userSecurityService.saveVerifyCode(id, verifyCode);
logger.info("-----------发送的验证码为:"+code);
vo.setSuccess(true);
vo.setMsg("成功发送验证码");
return vo;
} catch (Exception e) {
vo.setMsg("发送验证码失败");
vo.setSuccess(false);
return vo;
}
}
/**
* 忘记密码并重置
* @param passwordVo
* @return
*/
@RequestMapping(value = "/forgetPw",method = {RequestMethod.POST,RequestMethod.GET})
public OperateResultVo changePw(UpdataPasswordVo passwordVo){
OperateResultVo vo = new OperateResultVo();
String newPassword = passwordVo.getNewPassword();
String confirmPassword = passwordVo.getConfirmPassword();
String verifyCode = passwordVo.getVerifyCode();
String tel = passwordVo.getTel();
if (passwordVo == null) {
vo.setSuccess(false);
vo.setMsg("参数错误!");
return vo;
}
if(StringUtils.isEmpty(tel)) {
vo.setSuccess(false);
vo.setMsg("请输入登录账号");
return vo;
}
if(StringUtils.isEmpty(verifyCode)) {
vo.setSuccess(false);
vo.setMsg("请输入验证码");
return vo;
}
if(StringUtils.isEmpty(newPassword)) {
vo.setSuccess(false);
vo.setMsg("请输入新密码");
return vo;
}
if(StringUtils.isEmpty(confirmPassword)) {
vo.setSuccess(false);
vo.setMsg("请输入确认密码");
return vo;
}
if(!newPassword.equals(confirmPassword)) {
vo.setSuccess(false);
vo.setMsg("两次输入密码不一致请重新输入");
return vo;
}
if(newPassword.length() < 6) {
vo.setSuccess(false);
vo.setMsg("请输入六位以上的密码");
return vo;
}
try {
User user = userService.findByTelAndRoleActive(tel,Long.valueOf(38),Long.valueOf(37));
if(user == null) {
vo.setSuccess(false);
vo.setMsg("该账号不存在或未激活");
return vo;
}
Long userId = user.getId();
//从缓存中获取验证码
String code = userSecurityService.findCodeById(userId);
if(code == null) {
vo.setSuccess(false);
vo.setMsg("验证码已失效!");
return vo;
}
if(!code.equals(verifyCode)) {
vo.setSuccess(false);
vo.setMsg("验证码不正确!");
return vo;
}
//修改密码
logger.info("======修改的新密码为:",newPassword);
User result = userService.updatePassword(user, newPassword);
if (result == null) {
vo.setMsg("修改失败!");
}else{
vo.setSuccess(true);
vo.setMsg("修改成功!");
}
return vo;
}catch (Exception e) {
vo.setMsg("修改密码失败请联系管理员");
vo.setSuccess(false);
return vo;
}
}