文件管理(demo)注册时的邮件验证

写在开头:本篇文章记录于22年4月23,一个暖洋洋的下午

实现功能

用户在注册时需要输入邮件并完成验证,方可进行完整注册。

逻辑实现

---->前端邮箱输入栏右侧加一个发送邮件按钮

文件管理(demo)注册时的邮件验证_第1张图片

--->点击按钮,携带邮箱向后端发起发送邮件的请求

--->后端接收请求,生成5位随机验证码,一方面将验证码作为邮件内容发送,另一方面将验证码写入redis并设置1分钟的有效期。

--->前端用户收到验证码,提交注册表单(包含验证码)

--->后端接收到注册表单,现拿表单里的邮箱去redis进行验证码效验,若reids已没有验证码,返回验证码已失效,用邮箱查到的验证码表单不一致,则返回验证码错误,若效验成功则进行后续的账号验证与数据库的写入

--->前端验证码失效,按钮就显示重新发送,成功则跳转至登录页面

技术栈

前端:vue2.X + vue-admin-template

后端:springboot+mybatis-plus+mysql+springSecurity+jwt+shiro

代码实现(碍于篇幅,只显示关键代码,建议去文末的gitee仓库地址拉取文件管理项目(前后端)的完整代码)

依赖引入:

         
        
            org.springframework.boot
            spring-boot-starter-mail
        
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
        
            cn.hutool
            hutool-all
            5.7.13
        
       
        
            org.springframework.boot
            spring-boot-starter-mail
        

springboot配置

 #redis配置
  redis:
    # 地址
    host: 127.0.0.1
    # 端口号
    port: 6379
    # 密码(默认为空)
    password:
    # 超时时间,单位毫秒
    timeout: 3000
    # 数据库编号
    database: 0
    # 配置lettuce
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 1
        # 连接池中的最大空闲连接
        max-idle: 6
        # 连接池最大连接数(使用负值表示没有限制,不要配置过大,否则可能会影响redis的性能)
        max-active: 10
        # 连接池最大阻塞等待时间(使用负值表示没有限制);单位毫秒
        max-wait: 1000
      #关闭超时时间;单位毫秒
      shutdown-timeout: 200
#发送验证邮件
  mail:
    protocol: smtp
    host: smtp.qq.com
    port: 465
    #自己邮箱和协议密码(非邮箱密码)
    username: *******
    password: *******
    default-encoding: utf-8
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          ssl:
            enable: true
          socketFactory:
            port: 465
            class: javax.net.ssl.SSLSocketFactory

shiro配置

@Component
public class ShiroConfig {

    @Bean
    public RedisTemplate template(RedisConnectionFactory factory) {
        // 创建RedisTemplate对象
        RedisTemplate template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        // 定义Jackson2JsonRedisSerializer序列化对象
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常
        om.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance ,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        jacksonSeial.setObjectMapper(om);
        StringRedisSerializer stringSerial = new StringRedisSerializer();
        // redis key 序列化方式使用stringSerial
        template.setKeySerializer(stringSerial);
        // redis value 序列化方式使用jackson
        template.setValueSerializer(jacksonSeial);
        // redis hash key 序列化方式使用stringSerial
        template.setHashKeySerializer(stringSerial);
        // redis hash value 序列化方式使用jackson
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        return template;
    }
} 
  

发送邮件的service类

@Service
public class EmailService {
    @Value("${spring.mail.username}")
    private String sendEmailName;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private TemplateEngine templateEngine;
    @Resource
    private RedisTemplate redisTemplate ;

    //发送邮件
    public void sendEmail(String confirm,String email) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
            //设置邮件基本信息
            mimeMessageHelper.setSubject("欢迎来到李同学的文件管理系统:个人账号注册");
            mimeMessageHelper.setFrom(sendEmailName);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setSentDate(new Date());
            //设置邮件内容模板
            Context context = new Context();
            context.setVariable("confirm", confirm);
            //使用thymeleaf的模板引擎
            String text = templateEngine.process("email.html", context);
            mimeMessageHelper.setText(text, true);
            //发送邮件
            javaMailSender.send(mimeMessage);
            //将验证码写入redis并设置1分钟有效期
            redisTemplate.opsForValue().set(email, confirm, 1, TimeUnit.MINUTES);
        } catch (Exception  e) {
            e.printStackTrace();
        }
    }

}

使用的thymeleaf邮件模板(将该eamil.html放入resources/templates/下)




    
    


这是由李同学的文件上传与下载系统发送的邮件:请不要泄露你的激活码


你的激活码为:${}

用户注册的service

//用户注册
    public Result register(VoUser voUser){
        User user=new User();
        if(voUser==null) return Result.fail("注册信息未填写完整");
        String salt= RandomUtil.randomString(5);
        String password = DigestUtil.md5Hex(voUser.getPassword()+salt);
        //效验账户
        QueryWrapper query=new QueryWrapper<>();
        query.eq("username", voUser.getUsername())
                .or()
                .eq("email", voUser.getEmail())
                .or()
                .eq("phone_num", voUser.getPhoneNum());
        List list = userService.list(query);
        if(!list.isEmpty()) return Result.fail("邮箱或用户名或手机号已被注册");
        //效验验证码,用前端传来的邮箱去redis中查询验证码
        String confirm=(String) redisTemplate.opsForValue().get(voUser.getEmail());
        if(confirm==null) return Result.fail("验证码已失效,请重新发送");
        else {
            if(!confirm.equals(voUser.getConfirm())) return Result.fail("验证码不正确");
        }
        //效验完毕,写入数据库
        user.setUsername(voUser.getUsername());
        user.setEmail(voUser.getEmail());
        user.setPhoneNum(voUser.getPhoneNum());
        user.setSalt(salt);
        user.setPassword(password);
        user.setRole("ROLE_admin");
        userService.save(user);
        return Result.succ("注册成功");
    }

注册和发送邮件的controller

    //发送邮件
    @GetMapping("/sendEmail")
    public Result sendEmail(String email){
        //生成五位随机验证码,注入邮件,同时返回给前端由于验证
        String confirm= RandomUtil.randomString(5);
        emailService.sendEmail(confirm,email);
        return Result.succ(confirm);
    }
    //注册用户
    @RequestMapping("/register")
    public Result register(@RequestBody VoUser voUser) {
        return loginService.register(voUser);
    }

效果展示

文件管理(demo)注册时的邮件验证_第2张图片

文件管理(demo)注册时的邮件验证_第3张图片

 写在最后

本文主要展示了涉及邮件验证的核心代码,与springSecurity, jwt, 文件上传下载的代码均在仓库里

项目的完整代码在:gitee仓库地址

有用的话给个star~~~~ 

你可能感兴趣的:(邮件验证,spring,boot,java,vue,redis)