利用java实现用户注册qq邮箱发验证码

1.首先导入依赖


        
            org.springframework.boot
            spring-boot-starter-mail
        

//redis依赖

        
        
            org.springframework.boot
            spring-boot-starter-data-redis
            2.7.5
        

        
        
            org.springframework.session
            spring-session-data-redis
            2.7.0
        

进行redis的配置

@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate  redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(RedisSerializer.string());
        return redisTemplate;
    }
}
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {
    private String host;
    private String port;

    @Bean
    public RedissonClient redissonClient(){
        // 创建配置
        Config config = new Config();
        String redisAdress=String.format("redis://%s:%s",host,port);
        //setdatebase是指redis库号
        config.useSingleServer().setAddress(redisAdress).setDatabase(3);
        //创建实例
        RedissonClient redisson = Redisson.create(config);
        return redisson;
    }
}

appliication.yml

redis的配置

   #Resdis配置
  redis:
    port: 6379
    host: localhost
    database: 3

邮箱的配置

spring  
  mail:
    host: smtp.qq.com
    username: 你的邮箱账号
    password: 开通POP3之后会给你一个字符串
    default-encoding: utf-8
    properties:
        mail:
          smtp:
            auth: true
            starttls:
              enable: true
              required: true

2.进入qq邮箱电脑端(设置-账户),开启服务

 3.在usercontroller中创建接口

 @PostMapping("/sendMessage")
    public BaseResponse sendMessage(@RequestBody UserSendMessage userSendMessage) {
        log.info("userSendMessage:"+userSendMessage.toString());
        return userService.sendMessage(userSendMessage);
    }

创建实体类userSendMessage

@Data
public class UserSendMessage implements Serializable {

    private static final long serialVersionUID = 46412442243484364L;

    private String userEmail;
    private String code;

}

随机生成验证码

package com.kuang.utils;

import java.util.Random;

/**
 * 随机生成验证码工具类
 */
public class ValidateCodeUtils {
    /**
     * 随机生成验证码
     *
     * @param length 长度为4位或者6位
     * @return
     */
    public static Integer generateValidateCode(int length) {
        Integer code = null;
        if (length == 4) {
            code = new Random().nextInt(9999);//生成随机数,最大为9999
            if (code < 1000) {
                code = code + 1000;//保证随机数为4位数字
            }
        } else if (length == 6) {
            code = new Random().nextInt(999999);//生成随机数,最大为999999
            if (code < 100000) {
                code = code + 100000;//保证随机数为6位数字
            }
        } else {
            throw new RuntimeException("只能生成4位或6位数字验证码");
        }
        return code;
    }

    /**
     * 随机生成指定长度字符串验证码
     *
     * @param length 长度
     * @return
     */
    public static String generateValidateCode4String(int length) {
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

实现sendMessage方法,将验证码写入redis,为后面的用户注册校验验证码做准备

 /**
     * 发送验证码
     * @param toEmail
     * @return
     */
    @Override
    public BaseResponse sendMessage(UserSendMessage toEmail) {
        String email = toEmail.getUserEmail();
        if (StringUtils.isEmpty(email)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "email为空");
        }
        String subject = "****系统";
        String code = "";
        //StringUtils.isNotEmpty字符串非空判断
        if (StringUtils.isNotEmpty(email)) {
            //发送一个四位数的验证码,把验证码变成String类型
            code = ValidateCodeUtils.generateValidateCode(6).toString();
            String text = "【***系统】您好,您的验证码为:" + code + ",请在5分钟内使用";
            log.info("验证码为:" + code);
            //发送短信
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);
            message.setSubject(subject);
            message.setText(text);
            //发送邮件
            javaMailSender.send(message);
            UserSendMessage userSendMessage = new UserSendMessage();
            userSendMessage.setUserEmail(email);
            userSendMessage.setCode(code);
            // 作为唯一标识
            String redisKey = String.format("my:user:sendMessage:%s", email);
            ValueOperations valueOperations = redisTemplate.opsForValue();
            // 写缓存
            try {
                valueOperations.set(redisKey, userSendMessage, 300000, TimeUnit.MILLISECONDS);
                UserSendMessage sendMessage = (UserSendMessage) valueOperations.get(redisKey);
                log.info(sendMessage.toString());
                return ResultUtils.success(true);
            } catch (Exception e) {
                log.error("redis set key error", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "缓存失败!");
            }
        }
        return ResultUtils.success(true);
    }
}

用户注册功能

 @PostMapping("/register")
    public BaseResponse userRegister(@RequestBody UserRegisterRequest userRegisterRequest){
        if (userRegisterRequest == null){
          throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        String planetCode=userRegisterRequest.getPlanteCode();
        String userEmail = userRegisterRequest.getUserEmail();
        String code = userRegisterRequest.getCode();
        if (StringUtils.isAnyBlank(userAccount,userPassword,checkPassword,planetCode,code,userEmail)){
            throw new BusinessException(ErrorCode.NULL_ERROR,"不存在");
        }
        long result= userService.userRegister(userAccount,userPassword,checkPassword,planetCode,code,userEmail);
//        return new BaseResponse<>(0,result,"ok");
        return ResultUtils.success(result);

注册功能的实现

 //把yml配置的邮箱号赋值到from
    @Value("${spring.mail.username}")
    private String from;
    //发送邮件需要的对象
    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private RedisTemplate redisTemplate;


    @Override
    public long userRegister(String userAccount, String userPassword, String checkPassword,String planetCode,String code,String userEmail) {


        //同时判断三个参数是否为空
        if (StringUtils.isAnyBlank(userAccount,userPassword,checkPassword,planetCode,code,userEmail)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        //检验长度
        if(userAccount.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户账号过短");
        }
        if (planetCode.length()>5){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"星球账号过大");
        }
        if (userPassword.length()<8 || checkPassword.length()<8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户密码过短");
        }
        //账户不能包含特殊字符
//        String validPattern= "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if (matcher.find()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"含特殊字符");
        }
        //密码和校验密码相同
        if (!userPassword.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次密码输入不同");
        }

        //从ression获取验证码
        String redisKey = String.format("my:user:sendMessage:%s", userEmail);
        ValueOperations valueOperations = redisTemplate.opsForValue();
        log.info(redisKey);
        UserSendMessage sendMessage = (UserSendMessage) valueOperations.get(redisKey);
        //如果没有值,失败
        if (!Optional.ofNullable(sendMessage).isPresent()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "获取验证码失败!");
        }
        //比对验证码
        String sendMessageCode = sendMessage.getCode();
        log.info(sendMessageCode);
        if (!code.equals(sendMessageCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码不匹配!");
        }

        //账户不能重复使用,检验数据库中的数据是否与新创建的用户是否相同
        QueryWrapper queryWrapper=new QueryWrapper<>();
        //获取用户
        queryWrapper.eq("userAccount",userAccount);
        //计算用户数量
        long count = userMapper.selectCount(queryWrapper);
        log.info(count+"");
        if (count>0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"存在重复用户");
        }
        //星球编号不能重复使用
        queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("planetCode",planetCode);
         count = userMapper.selectCount(queryWrapper);
        if (count>0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"编号重复");
        }
        //加密密码,MD5算法加密
        String newPassword= DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
        //向数据库中插入数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(newPassword);
        user.setPlanetCode(planetCode);
        user.setEmail(userEmail);
        boolean saveResult= this.save(user);
        if (!saveResult){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"不存在用户");
        }
        return user.getId();
    }

qq邮箱的实现主要是发送消息后将消息缓存到redis,在用户进行注册的时候,将填写的验证码和缓存中的数据进行校验,如果相同实现注册,验证码正确。

你可能感兴趣的:(java,开发语言)