Spring Boot 整合网易163邮箱发送邮件实现找回密码功能

在开发用户系统时,发送邮件是一项常见需求,例如用户忘记密码时,通过邮箱发送验证码来验证身份并重置密码。本文将结合 Spring Boot 和 163 邮箱,演示如何实现邮件发送功能。


一、前提条件

普通用户的 163 邮箱可以在 Spring Boot 项目中用于发送邮件,但需要完成以下配置:

1. 登录 163 邮箱

使用普通账号登录 163 邮箱官网

2. 开启 SMTP 服务

  1. 点击邮箱右上角「设置」→「POP3/SMTP/IMAP」;
  2. 在 SMTP 服务选项中勾选「开启 SMTP 服务」;
  3. 按提示完成手机验证(163 邮箱要求绑定手机号才能开启该服务)。

3. 获取授权码

  1. 开启 SMTP 后,页面会提示生成授权码;
  2. 按照提示生成 16 位授权码(例如 abcdefghijklmnop),保存好;
  3. 该授权码将在 Spring Boot 邮件配置中替代邮箱密码。

⚠️ 注意:普通 163 邮箱每天发送量有限,适合开发和测试用途。


二、Spring Boot 邮件依赖

pom.xml 中添加 Spring Boot 邮件依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

三、Spring Boot 邮件配置

application.ymlapplication.properties 中添加 163 邮箱 SMTP 配置:

yaml 复制代码
spring:
# 配置邮箱服务器,账号密码等
  mail:
    host: smtp.163.com
    username: 1888888888@163.com
    password: agagtfgsdhd
    code:
      overtime: 5

其中 password 是生成的授权码,而非邮箱密码。


四、邮件发送服务实现

创建 MailService 接口:

java 复制代码
public interface MailService {
    Result<String> getCode(String username, String mailAddress);
}

创建 MailServiceImpl 实现类:

java 复制代码
@Service
public class MailServiceImpl implements MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Value("${spring.mail.username}")
    private String mailUserName;

    @Value("${spring.mail.code.overtime}")
    private Integer overtime; // 验证码过期时间(分钟)

    @Override
    public Result<String> getCode(String username, String mailAddress) {
        // 校验用户名和邮箱
        if (StringUtils.isBlank(username)) return Result.fail("账号不能为空!");
        if (StringUtils.isBlank(mailAddress)) return Result.fail("邮箱不能为空!");
        
        User user = userMapper.selectUserByUsername(username);
        if (user == null) return Result.fail("账号不存在!");
        if (!user.getEmail().equals(mailAddress)) return Result.fail("输入邮箱和预留邮箱不一致!");

        // 生成验证码
        String verifyCode = redisTemplate.opsForValue().get("MAIL_CODE_" + username);
        if (verifyCode == null) {
            verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);
        }
        redisTemplate.opsForValue().set("MAIL_CODE_" + username, verifyCode, overtime, TimeUnit.MINUTES);

        // 构建邮件内容
        String content = "<html><body>"
                + "您好<br/>"
                + "您的验证码是:" + verifyCode + "<br/>"
                + "在" + overtime + "分钟内有效,请尽快使用。<br/>"
                + "若非本人操作,请忽略此邮件。"
                + "</body></html>";

        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(mailUserName);
            helper.setTo(mailAddress);
            helper.setSubject("找回密码验证码");
            helper.setText(content, true);
            mailSender.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
            return Result.fail("邮件发送失败!");
        }

        return Result.ok("验证码已发送至邮箱:" + mailAddress);
    }
}

五、邮件控制器

java 复制代码
@RestController
@RequestMapping("/mail")
public class MailController {

    @Autowired
    private MailService mailService;

    @GetMapping("/getCode")
    @ApiOperation("获取重置密码验证码")
    public Result<String> getCode(String username, String mailAddress){
        return mailService.getCode(username, mailAddress);
    }
}

六、Redis 验证码存储

  • 使用 StringRedisTemplate 存储验证码:

    • Key: MAIL_CODE_用户名
    • Value: 验证码
    • TTL: spring.mail.code.overtime 分钟
  • 发送邮件后验证码会被存入 Redis,用户提交时进行比对。

相关推荐
ShadowYD3 小时前
Agent Loop:一个让 AI 编程 Agent 从"会写代码"进化到"闭环交付"的开源 Skill(适配国内外主流 Code Agent)
后端
考虑考虑5 小时前
nohup启动java程序
后端·自动化运维
Gigavision5 小时前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
IPdodo_6 小时前
跨境 API 调用不稳定怎么办:出口、超时重试与链路监控的实践
网络·python·网络协议
aramae6 小时前
模拟实现strcmp()(C语言)
c语言·开发语言·后端
Madison-No76 小时前
搭建项目测试环境
linux·运维·服务器·python
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
计算机编程-吉哥7 小时前
YOLO26 vs YOLO11 vs YOLOv8:深度学习咖啡果实成熟度分割系统【计算机毕业设计选题推荐】
人工智能·python·深度学习·yolo·django·毕业设计