本文使用 spring 框架中自带的 JavaMailSender 发送邮件,使用HttpSession 在服务器端保存会话信息,储存生成的验证码,以便客户端输入验证码进行验证,下面我们就来说一说关于springboot结合springsession?我们一起去了解并探讨一下这个问题吧!

springboot结合springsession(Session实现邮箱验证码验证)

springboot结合springsession

前置说明

本文使用 spring 框架中自带的 JavaMailSender 发送邮件,使用HttpSession 在服务器端保存会话信息,储存生成的验证码,以便客户端输入验证码进行验证。

邮箱验证码验证

众所周知,邮件可以包含很多种类的内容。在本文中,邮件内容分为:纯文本、HTML代码(Thymeleaf模板)、附件、图片。看完内容类型可以得知,其实内容为 HTML 代码或附件是最好用的。

验证流程:

1. 客户端发送获取验证码请求

2. 服务器端通过 VerifyCodeService 生成验证码,并将验证码放入 session 中

3. 服务器将验证码通过 MailService 发送到用户邮箱

4. 用户输入验证码,通过验证

代码示例

一、maven依赖

注意:starter-mail 要是 2.1.3.RELEASE 以下的,这样可以使用 JavaMailHelper,2.1.6.RELEASE 及以上不清楚调用什么api可以发邮件,感兴趣的同学可以查一下官方文档~

<!-- 邮件内容使用的模板引擎--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 注意:2.1.6没有JavaMailSender--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>2.1.3.RELEASE</version> </dependency>

二、application.properties 配置

application.properties 配置发送邮件以及使用模板的配置。

## mail config ## #163的SMTP服务器 spring.mail.host=smtp.163.com #发件邮箱的账号和密码 spring.mail.username=xxx@163.com spring.mail.password=xxx spring.mail.default-encoding=utf-8 ## thymeleaf config## spring.thymeleaf.mode=HTML5 spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.cache=false ## default config ## mail.from.addr=xxx@163.com

三、MailService(interface)

提供发送不同类型内容邮件的服务。

/** * @author amber */ public interface MailService { /** * 发送普通文本邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容 */ void sendSimpleMail(String to, String subject, String content); /** * 发送HTML邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容(可以包含<html>等标签) */ void sendHtmlMail(String to, String subject, String content); /** * 发送带附件的邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容 * @param filePath 附件路径 */ void sendAttachmentMail(String to, String subject, String content, String filePath); /** * 发送带图片的邮件 * * @param to 收件人 * @param subject 主题 * @param content 文本 * @param rscPath 图片路径 * @param rscId 图片ID,用于在<img>标签中使用,从而显示图片 */ void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId); }

四、MailServiceImpl

MailService 服务实现。

import com.amber.verifycode.service.MailService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import java.io.File; /** * @author amber */ @Service public class MailServiceImpl implements MailService { @Value("${mail.from.addr}") private String from; @Autowired JavaMailSender javaMailSender; @Override public void sendSimpleMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); //收信人 message.setTo(to); //主题 message.setSubject(subject); //内容 message.setText(content); //发信人 message.setFrom(from); try { javaMailSender.send(message); } catch (Exception e) { e.printStackTrace(); } } @Override public void sendHtmlMail(String to, String subject, String content) { try { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); //true代表支持html helper.setText(content, true); javaMailSender.send(message); } catch (MessagingException e){ } } @Override public void sendAttachmentMail(String to, String subject, String content, String filePath) { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper; try { helper = new MimeMessageHelper(message, true); //true代表支持多组件,如附件,图片等 helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content, true); FileSystemResource file = new FileSystemResource(new File(filePath)); String fileName = file.getFilename(); //添加附件,可多次调用该方法添加多个附件 helper.addAttachment(fileName, file); javaMailSender.send(message); } catch (MessagingException e) { } } @Override public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper; try { helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content, true); FileSystemResource res = new FileSystemResource(new File(rscPath)); //重复使用添加多个图片 helper.addInline(rscId, res); javaMailSender.send(message); } catch (MessagingException e) { } } }

五、VerifyCodeService

生成以及发送验证码的服务。

/** * @author amber */ public interface VerifyCodeService { /** * 随机生成6位验证码:大写英文字符 数字 * @return 验证码 */ String getEmailCode(); /** * 随机生成6位验证码,全部为数字组成。 * @return 验证码 */ String getPhoneCode(); /** * 发送验证码至相应邮箱 * @param to 收件人 * @param subject 主体 * @param verifyCode 内容 */ void sendCode2Email(String to, String subject, String verifyCode); }

六、VerifyCodeServiceImpl

VerifyCode服务的实现。

import com.amber.verifycode.service.MailService; import com.amber.verifycode.service.VerifyCodeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; /** * @author amber */ @Service public class VerifyCodeServiceImpl implements VerifyCodeService { @Autowired MailService mailService; @Autowired TemplateEngine templateEngine; @Override public String getEmailCode() { StringBuilder code = new StringBuilder(); int dir = 0; for (int i = 0; i < 8; i ) { dir = (Math.random() > 0.5) ? 1 : 0; if (dir == 1) { //拼数字 code.append((int) (Math.random() * 9)); } else { //拼字母 code.append(getRandomCapitalLetter()); } } return code.toString(); } @Override public String getPhoneCode() { StringBuilder code = new StringBuilder(); for (int i = 0; i < 6; i ) { code.append((int) (Math.random() * 9)); } return code.toString(); } @Override public void sendCode2Email(String to, String subject, String verifyCode) { //把验证码放到thymeleaf模板中 Context context = new Context(); context.setVariable("verifyCode", verifyCode); String emailContent = templateEngine.process("emailTemplate", context); //发送邮件 mailService.sendHtmlMail(to, subject, emailContent); } //随机生成大写英文字母 private char getRandomCapitalLetter() { int i = (int) (Math.random() * 25); //大写字母的ASCII值为65-90 int j = i 65; char letter = (char) j; return letter; } }

七、VerifyCodeController

这里 controller 只提供验证作用,实际业务场景可根据 HttpSession 提供的api进行设置。

import com.amber.verifycode.service.MailService; import com.amber.verifycode.service.VerifyCodeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * @author amber */ @Controller @RequestMapping("/verifyCode") public class VerifyCodeController { @Autowired MailService mailService; @Autowired VerifyCodeService verifyCodeService; @RequestMapping("/mail") @ResponseBody public Object sendVerifyCode(HttpServletRequest request, HttpServletResponse response) { String verifyCode = verifyCodeService.getEmailCode(); verifyCodeService.sendCode2Email("xx@qq.com", "SimpleTest", verifyCode); HttpSession session = request.getSession(false); if (session == null) { //创建session,并拿到JSESSIONID session = request.getSession(); } //设置session有效时间,默认是1800s session.setMaxInactiveInterval(900); //将验证码放入session中 session.setAttribute("verifyCode", verifyCode); return "success!"; } @RequestMapping("/verify") @ResponseBody public Object verify(String inputCode, HttpServletRequest request){ HttpSession session = request.getSession(); String verifyCode = (String) session.getAttribute("verifyCode"); if (inputCode.equals(verifyCode)){ //主动使session无效 session.invalidate(); return true; } return false; } }

八、emailTemplate.html

邮件内容模板。

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 您好,本次验证的验证码为:[[${verifyCode}]] </body> </html>

,