java实现邮箱验证码登录核心代码
实现思路
- 前端发送请求获取验证码
- 后端生成验证码和key,缓存key和验证码,将验证码发送到邮箱
- 前端携带验证码和key调用后端接口校验,校验成功则登录否则弹出错误提示
实现过程
引入依赖
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<!-- 缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
创建邮件发送工具类
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
public class EmailSenderUtil {
// 发送邮件的配置
private String host = "smtp.qq.com"; // 邮箱服务器地址
private String port = "587"; // 邮箱服务器端口
private String userName = "973016735@qq.com"; // QQ邮箱地址
private String password = "jlfstnepnifgbfha"; // QQ邮箱授权码
public EmailSenderUtil(){
}
public EmailSenderUtil(String host, String port, String userName, String password) {
this.host = host;
this.port = port;
this.userName = userName;
this.password = password;
}
/**
* 发送纯文本邮件
*
* @param to 收件人地址
* @param subject 邮件主题
* @param text 邮件正文
* @throws MessagingException 发送邮件时可能抛出异常
*/
public void sendPlainTextEmail(String to, String subject, String text) throws MessagingException {
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(userName));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setText(text);
Transport.send(message);
}
/**
* 发送HTML格式邮件
*
* @param to 收件人地址
* @param subject 邮件主题
* @param html 邮件正文(HTML格式)
* @throws MessagingException 发送邮件时可能抛出异常
*/
public void sendHtmlEmail(String to, String subject, String html) throws MessagingException {
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(userName));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setContent(html, "text/html; charset=utf-8");
Transport.send(message);
}
// public static void main(String[] args) throws Exception {
// EmailSenderUtil emailSenderUtil = new EmailSenderUtil();
// emailSenderUtil.sendPlainTextEmail("973016735@qq.com", "测试邮件", "测试邮件正文");
// }
}
springboot启动类中开启缓存
@SpringBootApplication
@EnableCaching //开启缓存
@MapperScan(basePackages = {"com.dao"})
public class SpringbootSchemaApplication extends SpringBootServletInitializer{
}
CodeServiceImpl
这个主要用来实现验证码的缓存
package com.service.impl;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class CodeServiceImpl {
//创建验证码 --- 加入缓存中
@CachePut(value = "myCache", key = "#codeKey")
public String cacheCode(String codeKey,String code){
System.out.println("缓存:"+codeKey);
return code;
}
//查询验证码 --- 有就从缓存中取,没有就返回null
@Cacheable(value = "myCache")
public String getCacheCode(String codeKey){
System.out.println("不走缓存,"+codeKey);
return null;
}
}
controller中的核心代码
@Autowired
private CodeServiceImpl codeService;
@Autowired
private TokenService tokenService;
//生成随机验证码
public String getRandomCode(int length) {
String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 获取邮件验证码
* @return
*/
@IgnoreAuth
@GetMapping("/getCode")
public R getCode(String email) {
List<YonghuEntity> yonghuEntityList = yonghuService.selectList(new EntityWrapper<YonghuEntity>().eq("email", email));
if(yonghuEntityList.size() == 0) {
return R.error("此邮箱未在系统中注册");
}
String codeKey = UUID.randomUUID().toString().replace("-","");//生成验证码key
String verifyCode = getRandomCode(4); //生成验证码
codeService.cacheCode(codeKey,verifyCode);//缓存key和验证码
System.out.println("生成验证码:"+verifyCode);
//发送验证码邮件
EmailSenderUtil emailSenderUtil = new EmailSenderUtil();
try {
emailSenderUtil.sendPlainTextEmail(email, "您的邮件登录验证码为:", "您的验证码为:"+verifyCode);
} catch (MessagingException e) {
throw new RuntimeException(e);
}
//返回验证码key
return R.ok().put("codeKey", codeKey);
}
/**
* 邮箱登录
*/
@IgnoreAuth
@GetMapping("/emailLogin")
public R emailLogin(String username, String password,String email, String code,String codeKey) {
YonghuEntity u = yonghuService.selectOne(new EntityWrapper<YonghuEntity>().eq("yonghuzhanghao", username));
if(u==null || !u.getMima().equals(password)) {
return R.error("账号或密码不正确");
}
if(!u.getEmail().equals(email)){
return R.error("邮箱和当前登录账号不一致");
}
String verifyCode = codeService.getCacheCode(codeKey);
if(verifyCode == null || !verifyCode.equals(code)) {
return R.error("验证码错误");
}
String token = tokenService.generateToken(u.getId(), u.getYonghuzhanghao(),"yonghu", "用户" );
return R.ok().put("token", token).put("username", u.getYonghuzhanghao());
}

