目录
一、简介
二、代码实现
1. 添加pom依赖
2. 创建邮件发送信息传输类、授权信息类
3. 创建邮箱服务接口和实现类
4. 修改配置文件application.yml,添加相关配置信息
5. 创建邮件模板
6. 创建功能服务接口与实现类
7. 编写Controller层API接口
三、结果演示
1. 发送邮箱验证码接口
2. 注册账号接口
3. 验证码邮件示例编辑
用户注册系统时,一般会以邮箱进行关联注册,需要用户输入邮箱地址以获取随机验证码,然后在注册页面输入该验证码并完善其他相关注册信息点击注册,完成注册。
基于SpringBoot的后端开发项目实现的逻辑分为两步:
org.springframework.boot
spring-boot-starter-data-redis
cn.hutool
hutool-all
5.5.7
javax.mail
mail
1.4.7
org.springframework.boot
spring-boot-starter-freemarker
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmailDto {
/**
* 发送邮箱列表
*/
private List tos;
/**
* 主题
*/
private String subject;
/**
* 内容
*/
private String content;
}
@ApiModel(value = "授权用户信息")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthUserDto {
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "临时登录凭证")
private String code;
@ApiModelProperty(value = "邮箱")
private String email ;
}
public interface EmailService {
/**
* 发送邮件
*
* @param emailDto 邮箱列表
*/
void send(EmailDto emailDto);
}
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {
@Value("${spring.mail.email}")
private String email;
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.port}")
private String port;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Override
public void send(EmailDto emailDto) {
// 读取邮箱配置
if (email == null || host == null || port == null || username == null || password == null) {
throw new RuntimeException("邮箱配置异常");
}
// 设置
MailAccount account = new MailAccount();
account.setHost(host);
account.setPort(Integer.parseInt(port));
// 设置发送人邮箱
account.setFrom(username + "<" + email + ">");
// 设置发送人名称
account.setUser(username);
// 设置发送授权码
account.setPass(password);
account.setAuth(true);
// ssl方式发送
account.setSslEnable(true);
// 使用安全连接
account.setStarttlsEnable(true);
// 发送邮件
try {
int size = emailDto.getTos().size();
Mail.create(account)
.setTos(emailDto.getTos().toArray(new String[size]))
.setTitle(emailDto.getSubject())
.setContent(emailDto.getContent())
.setHtml(true)
//关闭session
.setUseGlobalSession(false)
.send();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
mail:
# 负责发送验证码的邮箱
email: [email protected]
host: smtp.126.com
port: 465
username: XXXX
# 授权码是用于登录第三方邮件客户端的专用密码。
password: XXXXXXXXX
#邮箱验证码有效时间/秒
code:
expiration: 300
此处授权密码需要在邮箱中申请配置,如下获取一个授权密码:【登录邮箱】-【设置】,springboot即可通过邮箱+授权码自动发送验证码邮件:
尊敬的用户,您好:
您正在注册【XXX平台】账号,您的验证码为:
${code}
public interface AuthService {
/**
* 向指定邮箱发送验证码
*
* @param email 邮箱号
* @return 结果
*/
RespBean sendMailCode(String email);
/**
* 注册
*
* @param authUserDto 认证用户请求信息
* @return 是否成功
*/
RespBean register(AuthUserDto authUserDto);
}
主要实现两个功能
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class AuthServiceImpl implements AuthService {
@Value("${code.expiration}")
private Long expiration;
// private final IAdminService adminService;
// private final RedisUtils redisUtils;
private final EmailService emailService;
private final PasswordEncoder passwordEncoder;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private AdminServiceImpl adminService;
@Override
@Transactional(rollbackFor = Exception.class)
public RespBean register(AuthUserDto authUserDto) {
ValueOperations valueOperations = redisTemplate.opsForValue();
// 通过email获取redis中的code
Object value = valueOperations.get(authUserDto.getEmail());
if (value == null || !value.toString().equals(authUserDto.getCode())) {
return RespBean.error("无效验证码!");
}
// 如果前端没有传入用户名,则以邮箱号作为用户名进行注册
String userName = StringUtils.isEmpty(authUserDto.getUsername()) ? authUserDto.getEmail() : authUserDto.getUsername();
if (adminService.getAdminByUserName(userName) != null) {
return RespBean.error("用户名已存在!");
}
// 创建用户
Admin admin = new Admin();
admin.setUsername(userName);
try {
admin.setPassword(passwordEncoder.encode(authUserDto.getPassword()));
} catch (Exception e) {
return RespBean.error("注册密码异常!");
}
admin.setEmail(authUserDto.getEmail());
if(adminService.create(admin) == null){
return RespBean.error("用户注册失败!");
};
redisTemplate.delete(authUserDto.getEmail());
return RespBean.success("用户注册成功!");
}
@Override
public RespBean sendMailCode(String email) {
ValueOperations valueOperations = redisTemplate.opsForValue();
// 查看注册邮箱是否存在
if (adminService.registerEmailExist(email)) {
return RespBean.error("邮箱已被注册!");
}
// 获取发送邮箱验证码的HTML模板
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));
Template template = engine.getTemplate("email-code.ftl");
// 从redis缓存中尝试获取验证码
Object code = valueOperations.get(email);
if (code == null) {
// 如果在缓存中未获取到验证码,则产生6位随机数,放入缓存中
code = RandomUtil.randomNumbers(6);
try {
valueOperations.set(email, code, expiration, TimeUnit.SECONDS);
} catch (Exception e) {
return RespBean.error("后台缓存服务异常");
}
}
// 发送验证码
emailService.send(new EmailDto(Collections.singletonList(email),
"邮箱验证码", template.render(Dict.create().set("code", code))));
return RespBean.success("验证码发送成功");
}
}
@Api(tags = "admin-controller")
@RestController
@RequestMapping("/user")
public class AdminController {
@Autowired
AuthServiceImpl authService;
@ApiOperation(value = "发送邮箱验证码")
@PostMapping("/getemailcode")
public RespBean getEmailCode(@RequestParam String email) {
return authService.sendMailCode(email);
}
@ApiOperation(value = "注册")
@PostMapping("/register")
public RespBean register(@RequestBody AuthUserDto authUserDto) {
return authService.register(authUserDto);
}
}
根据原项目完善用户服务类(adminService)相关的方法实现,即可实现邮箱验证码注册功能。
请求方式:post
请求地址:/user/getemailcode
参数:
{
"email": "[email protected]"
}
请求方式:post
请求地址:/user/register
参数:
{
"code": "214941",
"email": "[email protected]",
"password": "123",
"username": "myself"
}
参考:手把手教你通过SpringBoot实现邮箱注册码验证_智慧zhuhuix的博客-CSDN博客_springboot实现邮箱注册https://blog.csdn.net/jpgzhu/article/details/119533833