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,用户提交时进行比对。

相关推荐
代码的小搬运工2 小时前
网络请求(NSURL、NSURLRequest、NSURLSessionDataTask、协议回调与 JSON 数据的基本流向)
网络·数据库·json
Cx330❀7 小时前
【MySQL基础】一文吃透“表的约束”:从 Null/Default 到主外键的终极安全法则
linux·服务器·数据库·c++·mysql·安全
c238568 小时前
第二篇:《测试指挥官:可视化单题自测框架(含 assert 实操)》
java·数据库·c++·算法·安全性测试
大阳光男孩8 小时前
Spring Boot 整合 Debezium 实现 MySQL 增量数据监听(嵌入式版)
spring boot·后端·mysql
我科绝伦(Huanhuan Zhou)8 小时前
MySQL极端场景数据丢失防护:从Crash-Safe到异地备份
数据库·mysql
皮皮林5518 小时前
ThreadLocal 不香了?ScopedValue才是王道?
后端
辞旧 lekkk8 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
吴声子夜歌8 小时前
Redis 3.x——集群节点通信
redis·缓存·集群
明志数科9 小时前
人形机器人格斗场景下的技术挑战:动力学控制、感知融合与实时决策
网络·数据库
酉鬼女又兒9 小时前
零基础入门 DeepSeek V4 Pro API 开发:从环境搭建、消息格式规范到翻译函数实战、少样本提示、多轮对话聊天机器人与常见报错全流程详解指南
大数据·网络·数据库·人工智能·macos·机器人·github