基于SpringBoot实现邮箱验证码注册

目录

一、简介

二、代码实现

1. 添加pom依赖

2. 创建邮件发送信息传输类、授权信息类

3. 创建邮箱服务接口和实现类

4. 修改配置文件application.yml,添加相关配置信息

5. 创建邮件模板

6. 创建功能服务接口与实现类

7. 编写Controller层API接口

三、结果演示

1. 发送邮箱验证码接口

2. 注册账号接口

3. 验证码邮件示例​编辑


一、简介

        用户注册系统时,一般会以邮箱进行关联注册,需要用户输入邮箱地址以获取随机验证码,然后在注册页面输入该验证码并完善其他相关注册信息点击注册,完成注册。

        基于SpringBoot的后端开发项目实现的逻辑分为两步:

  1. 向邮箱发送随机验证码;
  2. 收到用户输入验证码进行校验完成注册;

二、代码实现

1. 添加pom依赖

    
    
      org.springframework.boot
      spring-boot-starter-data-redis
    
    
    
      cn.hutool
      hutool-all
      5.5.7
    
    
    
      javax.mail
      mail
      1.4.7
    
    
    
      org.springframework.boot
      spring-boot-starter-freemarker
    

2. 创建邮件发送信息传输类、授权信息类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmailDto {

    /**
     * 发送邮箱列表
     */
    private List tos;

    /**
     * 主题
     */
    private String subject;

    /**
     * 内容
     */
    private String content;

}
@ApiModel(value = "授权用户信息")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthUserDto {


    @ApiModelProperty(value = "用户名")
    private String username;

    @ApiModelProperty(value = "密码")
    private String password;

    @ApiModelProperty(value = "临时登录凭证")
    private String code;

    @ApiModelProperty(value = "邮箱")
    private String email ;

}

3. 创建邮箱服务接口和实现类

public interface EmailService {

    /**
     * 发送邮件
     *
     * @param emailDto 邮箱列表
     */
    void send(EmailDto emailDto);
}
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {

    @Value("${spring.mail.email}")
    private String email;
    @Value("${spring.mail.host}")
    private String host;
    @Value("${spring.mail.port}")
    private String port;
    @Value("${spring.mail.username}")
    private String username;
    @Value("${spring.mail.password}")
    private String password;

    @Override
    public void send(EmailDto emailDto) {

        // 读取邮箱配置
        if (email == null || host == null || port == null || username == null || password == null) {
            throw new RuntimeException("邮箱配置异常");
        }

        // 设置
        MailAccount account = new MailAccount();
        account.setHost(host);
        account.setPort(Integer.parseInt(port));
        // 设置发送人邮箱
        account.setFrom(username + "<" + email + ">");
        // 设置发送人名称
        account.setUser(username);
        // 设置发送授权码
        account.setPass(password);
        account.setAuth(true);
        // ssl方式发送
        account.setSslEnable(true);
        // 使用安全连接
        account.setStarttlsEnable(true);

        // 发送邮件
        try {
            int size = emailDto.getTos().size();
            Mail.create(account)
                    .setTos(emailDto.getTos().toArray(new String[size]))
                    .setTitle(emailDto.getSubject())
                    .setContent(emailDto.getContent())
                    .setHtml(true)
                    //关闭session
                    .setUseGlobalSession(false)
                    .send();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

    }
}

4. 修改配置文件application.yml,添加相关配置信息

mail:
    # 负责发送验证码的邮箱
    email: [email protected]
    host: smtp.126.com
    port: 465
    username: XXXX
    # 授权码是用于登录第三方邮件客户端的专用密码。
    password: XXXXXXXXX



#邮箱验证码有效时间/秒
code:
  expiration: 300

此处授权密码需要在邮箱中申请配置,如下获取一个授权密码:【登录邮箱】-【设置】,springboot即可通过邮箱+授权码自动发送验证码邮件:

基于SpringBoot实现邮箱验证码注册_第1张图片

5. 创建邮件模板




    
    


尊敬的用户,您好:

您正在注册【XXX平台】账号,您的验证码为:

${code}

6. 创建功能服务接口与实现类

public interface AuthService {

    /**
     * 向指定邮箱发送验证码
     *
     * @param email 邮箱号
     * @return 结果
     */
    RespBean sendMailCode(String email);

    /**
     * 注册
     *
     * @param authUserDto 认证用户请求信息
     * @return 是否成功
     */
    RespBean register(AuthUserDto authUserDto);
}

 主要实现两个功能

  1. 向邮箱发送随机验证码;sendMailCode
  2. 收到用户输入验证码进行校验完成注册;register
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class AuthServiceImpl implements AuthService {

    @Value("${code.expiration}")
    private Long expiration;

//    private final IAdminService adminService;
//    private final RedisUtils redisUtils;
    private final EmailService emailService;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AdminServiceImpl adminService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RespBean register(AuthUserDto authUserDto) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        // 通过email获取redis中的code
        Object value = valueOperations.get(authUserDto.getEmail());
        if (value == null || !value.toString().equals(authUserDto.getCode())) {
            return RespBean.error("无效验证码!");
        }

        // 如果前端没有传入用户名,则以邮箱号作为用户名进行注册
        String userName = StringUtils.isEmpty(authUserDto.getUsername()) ? authUserDto.getEmail() : authUserDto.getUsername();

        if (adminService.getAdminByUserName(userName) != null) {
            return RespBean.error("用户名已存在!");
        }

        // 创建用户
        Admin admin = new Admin();
        admin.setUsername(userName);
        try {
            admin.setPassword(passwordEncoder.encode(authUserDto.getPassword()));
        } catch (Exception e) {
            return RespBean.error("注册密码异常!");
        }
        admin.setEmail(authUserDto.getEmail());
        if(adminService.create(admin) == null){
            return RespBean.error("用户注册失败!");
        };
        redisTemplate.delete(authUserDto.getEmail());
        return RespBean.success("用户注册成功!");
    }



    @Override
    public RespBean sendMailCode(String email) {

        ValueOperations valueOperations = redisTemplate.opsForValue();

        // 查看注册邮箱是否存在
        if (adminService.registerEmailExist(email)) {
            return RespBean.error("邮箱已被注册!");
        }

        // 获取发送邮箱验证码的HTML模板
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));
        Template template = engine.getTemplate("email-code.ftl");

        // 从redis缓存中尝试获取验证码
        Object code = valueOperations.get(email);
        if (code == null) {
            // 如果在缓存中未获取到验证码,则产生6位随机数,放入缓存中
            code = RandomUtil.randomNumbers(6);
            try {
                valueOperations.set(email, code, expiration, TimeUnit.SECONDS);
            } catch (Exception e) {
                return RespBean.error("后台缓存服务异常");
            }
        }
        // 发送验证码
        emailService.send(new EmailDto(Collections.singletonList(email),
                "邮箱验证码", template.render(Dict.create().set("code", code))));
        return RespBean.success("验证码发送成功");

    }
}

7. 编写Controller层API接口

@Api(tags = "admin-controller")
@RestController
@RequestMapping("/user")
public class AdminController {

    @Autowired
    AuthServiceImpl authService;

    @ApiOperation(value = "发送邮箱验证码")
    @PostMapping("/getemailcode")
    public RespBean getEmailCode(@RequestParam String email) {
        return authService.sendMailCode(email);
    }

    @ApiOperation(value = "注册")
    @PostMapping("/register")
    public RespBean register(@RequestBody AuthUserDto authUserDto) {
        return authService.register(authUserDto);
    }

}

根据原项目完善用户服务类(adminService)相关的方法实现,即可实现邮箱验证码注册功能。

三、结果演示

1. 发送邮箱验证码接口

  • 请求方式:post

  • 请求地址:/user/getemailcode

  • 参数:

    { 
        "email": "[email protected]"
    }

2. 注册账号接口

  • 请求方式:post

  • 请求地址:/user/register

  • 参数:

    {
    	 "code": "214941",
    	 "email": "[email protected]",
    	 "password": "123",
    	 "username": "myself"
    }

3. 验证码邮件示例基于SpringBoot实现邮箱验证码注册_第2张图片

 参考:手把手教你通过SpringBoot实现邮箱注册码验证_智慧zhuhuix的博客-CSDN博客_springboot实现邮箱注册icon-default.png?t=M4ADhttps://blog.csdn.net/jpgzhu/article/details/119533833

你可能感兴趣的:(spring,boot,java,后端)