Spring:邮箱验证码
既然谈到了邮箱验证码,肯定是我们后端通过某些操作把验证码发送到用户的邮箱里。
我们首先讲解Spring如何发送邮箱
其实我之前已经写过了一篇文章:
实现Spring发送邮件 - 云端的解构者 | 西行寺岩羊的博客
请先阅读这篇文章,然后按照文章的操作对Spring进行配置。
配置好之后,我们就拿到了发送邮件接口。
这里我把MailService贴出来供大家参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @Service public class MailService { @Autowired private JavaMailSenderImpl javaMailSender; @Value("${spring.mail.username}") private String sendMailer;
private void checkMail(String to,String subject,String text){ if(StringUtils.isEmpty(to)){ throw new RuntimeException("邮件收信人不能为空"); } if(StringUtils.isEmpty(subject)){ throw new RuntimeException("邮件主题不能为空"); } if(StringUtils.isEmpty(text)){ throw new RuntimeException("邮件内容不能为空"); } } public void sendHtmlMailMessage(String to,String subject,String text){ checkMail(to,subject,text); try { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true); mimeMessageHelper.setFrom(sendMailer); mimeMessageHelper.setTo(to.split(",")); mimeMessageHelper.setSubject(subject); mimeMessageHelper.setText(text,true); mimeMessageHelper.setSentDate(new Date()); javaMailSender.send(mimeMessageHelper.getMimeMessage()); System.out.println("发送邮件成功:"+sendMailer+"->"+to); } catch (MessagingException e) { e.printStackTrace(); System.out.println("发送邮件失败:"+e.getMessage()); } }
|
这一段Service代码是针对html格式的邮箱内容进行编写的,没错,邮箱支持HTML格式,而且很多平台发送邮箱验证码都是使用这种格式,比如大家最喜欢的 Steam 平台。
如果大家需要纯文本格式的邮件发送代码,请参考上面我之前写的一篇文章。
我对邮件发送的Service已经封装好了,在Controller层可以直接拿来就用。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@RequestMapping("/sendMailCaptcha") public void sendHtmlMailMessage(String to) { String subject = "曦光录"; String code = generateSixDigitCode(); redisUtil.set(to + "code", code, 1); String content = "邮箱内容"; mailService.sendHtmlMailMessage(to, subject, content); }
|
请看这段代码,我首先调用了一个生成验证码的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Component public class GetCaptcha { private static final String CHARACTERS = "0123456789";
public static String generateSixDigitCode() { StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < 6; i++) { int index = random.nextInt(CHARACTERS.length()); char randomChar = CHARACTERS.charAt(index); sb.append(randomChar); } return sb.toString(); } }
|
这里注意看,我们在class的上方使用了@Component,如果大家不认识它,那么就参考
[[Spring:整体思路讲解#^78644d|@Component]]
曦光录登录模块概述 - 云端的解构者 | 西行寺岩羊的博客
CTRL+F搜索:UserService是怎么被发现的?
上文中的Controller代码中使用了一个重要的模块—— Redis
redisUtil.set(to + "code", code, 1);
Redis的基础介绍和应用请参考
[[Spring:Redis]]
Spring:Redis - 云端的解构者 | 西行寺岩羊的博客
Redis文章和接下来的内容可能有些许重复
实例
直接看这个罢(懒
代码在实例中已经有了,讲讲思路
在上文代码中我们已经实现了:
- 生成验证码
- 以HTML的形式把验证码发送到用户邮箱里
- 以「用户id+code:验证码」的形式存储到Redis中
那么,该如何验证呢?
我们可以把验证码和用户的登录或者注册信息一并发送到后端,比如
1 2 3 4 5 6 7 8
| { user:{ name:zheep, password:114514, ... } code:10086 }
|
这样后端在接收到数据后,在Service层中,先对验证码进行校验:
1 2 3 4 5 6 7 8 9 10 11 12
| String redisCode = redisUtil.get(userDTO.getEmail() + "code", new TypeReference<String>() {});
if (code.isEmpty()) { throw new BaseException("请输入验证码"); } if (redisUtil.get(redisCode) == null){ throw new BaseException("验证码已过期"); } if (!code.equals(redisCode)) { throw new BaseException("验证码错误"); } redisUtil.delete(redisCode)
|