从0到1学SpringCloud第二篇:邮箱和验证码业务实现


前期的准备后,接下来就可以编写业务逻辑代码。本文就针对于邮箱的发送邮件,验证码服务的生成以及校验的逻辑进行实现。

1. 邮箱服务接口

lagou-service-email项目

1.1 在pom.xml配置文件中添加邮件的依赖

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>

1.2 在application.yml中增加邮箱的配置

邮件服务器的配置要根据个人实际环境进行设置

1.3 创建EmailConfig配置类

@Getter
@Setter
@Configuration
public class EmailConfig {
    /**
     * 发送邮件服务器
     */
    @Value("${spring.mail.host}")
    private String host;
    /**
     * stmp的端口
     */
    @Value("${spring.mail.smtp.port}")
    private Integer port;
    /**
     * 发送邮件地址,和user一样
     */
    @Value("${spring.mail.from}")
    private String from;
    /**
     * 发送邮件的邮箱地址
     */
    @Value("${spring.mail.user}")
    private String user;
    /**
     * 客户端授权码,非邮箱密码
     */
    @Value("${spring.mail.pass}")
    private String pass;
}

1.4 创建EmailController控制类

创建一个发送邮件的方法send。这里通过了Hutool提供的MailUtil工具类来实现邮件发送

@RestController
@RequestMapping("emails")
public class EmailController {
    @Autowired
    private EmailConfig emailConfig;

    @GetMapping("send")
    public String send(@RequestParam String email, @RequestParam String code) {
        boolean result = sendEmail(email, code);
        return result ? "ok" : "error";
    }

    private boolean sendEmail(String email, String code) {
        try {
            MailAccount account = new MailAccount();
            account.setHost(emailConfig.getHost());
            account.setPort(emailConfig.getPort());
            account.setFrom(emailConfig.getFrom());
            account.setUser(emailConfig.getUser());
            account.setPass(emailConfig.getPass());

            MailUtil.send(account, email, "账号激活邮件", "您的验证码是:" + code + "。有效期10分钟,请尽快输入验证", false);

            return true;

        }catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
}

1.5 测试发送邮件的接口

  • 启动服务,在控制台中输入以下命令进行测试,提供邮箱参数和验证码参数的值。当发送成功则会返回ok
curl http://localhost:8082/emails/send?email=yaohuiye@126.com&code=123456
  • 进入对应邮箱,查看是否收到验证码邮件

2. 验证码服务接口

lagou-service-code项目

需要跟数据表lagou_auth_code进行数据交互,之前已经在此项目中引入了数据源和JPA框架,接下来就要实现创建验证码和校验验证码的接口

2.1 创建实体类Code

@Data
@Entity
@Table(name = "lagou_auth_code")
public class Code {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //邮箱
    private String email;
    //验证码
    private String code;
    //创建时间
    private LocalDateTime createTime;
    //过期时间
    private LocalDateTime expireTime;
}

2.2 创建数据访问接口CodeDao

直接实现JPA提供的通用接口JpaRepository

public interface CodeDao extends JpaRepository<Code, Long> {
}

2.3 创建业务接口CodeService

提供创建验证码createCode和校验checkCode的接口方法

public interface CodeService {
    /**
     * 创建验证码
     * @param email
     * @return
     */
    String createCode(String email);

    /**
     * 校验验证码
     * @param email
     * @param code
     * @return  0表示正确,1表示错误,2表示超时
     */
    Integer checkCode(String email, String code);
}

2.4 创建业务接口实现类CodeServiceImpl

  • 实现接口CodeService 对创建验证码接口方法进行实现。随机生成6位数字的验证码,设置过期时间为10分钟,存放到数据库表中 对校验接口方法进行实现。通过邮箱到数据库中拿对应的验证码,判断是否过期,是否相等,返回不同的结果值
@Service
public class CodeServiceImpl implements CodeService {
    @Autowired
    private CodeDao codeDao;
    
    @Override
    public String createCode(String email) {
        //随机验证码
        String code = RandomUtil.randomNumbers(6);
        //创建时间
        LocalDateTime createTime = LocalDateTime.now();
        //过期时间:10分钟后过期
        LocalDateTime expireTime = createTime.plusMinutes(10L);

        //判断是否已存在
        Optional<Code> codeOptional = getByEmail(email);
        Code entity = new Code();
        entity.setId(codeOptional.isPresent() ? codeOptional.get().getId() : null);
        entity.setCode(code);
        entity.setEmail(email);
        entity.setCreateTime(createTime);
        entity.setExpireTime(expireTime);
        codeDao.save(entity);

        return code;
    }

    @Override
    public Integer checkCode(String email, String code) {
        if(StrUtil.isBlank(email) || StrUtil.isBlank(code)) {
            return 1;
        }
        Optional<Code> codeOptional = getByEmail(email);
        if(codeOptional.isPresent()) {
            if(LocalDateTime.now().compareTo(codeOptional.get().getExpireTime()) > 0) {
                return 2;
            }
            if(code.equals(codeOptional.get().getCode())) {
                return 0;
            }
        }
        return 1;
    }

    private Optional<Code> getByEmail(String email) {
        Code code = new Code();
        code.setEmail(email);
        return codeDao.findOne(Example.of(code));
    }
}

2.5 创建控制类CodeController

  • 提供生成验证码的请求方法,路由是codes/create?email=#邮箱# 当生成验证码后,需要调用邮箱服务lagou-service-email提供的发送邮件方法,进行验证码的发送。这里通过了Hutool提供的HttpUtil工具类进行http请求的调用 提供校验验证码的请求方法,路由是codes/validate?email=#邮箱#&code=#验证码#
@RestController
@RequestMapping("codes")
public class CodeController {
    @Autowired
    private CodeService codeService;


    @GetMapping("create")
    public String create(@RequestParam String email) {
        //生成验证码并发送到对应的邮箱中
        //生成验证码
        String code = codeService.createCode(email);
        //发送验证码到邮箱中
        return sendEmail(email, code);
    }


    @GetMapping("validate")
    public Integer validate(@RequestParam String email, @RequestParam String code) {
        //校验验证码是否正确
        Integer result = codeService.checkCode(email, code);
        return result;
    }

    private String sendEmail(String email, String code) {
        String url = "http://localhost:8082/emails/send?email=" + email + "&code=" + code;
        String response = HttpUtil.get("http://localhost:8082/emails/send?email=" + email + "&code=" + code);
        return response;
    }
}

2.6 测试接口

  • 需要启动邮箱服务、验证码服务 创建验证码测试
curl http://localhost:8083/codes/create?email=yaohuiye@126.com
  • 校验验证码测试
curl http://localhost:8083/codes/validate?email=yaohuiye@126.com&code=123456

3. 参考代码

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/290363.html

(0)
上一篇 2022年10月2日
下一篇 2022年10月2日

相关推荐

发表回复

登录后才能评论