发送邮箱验证码功能实现
This commit is contained in:
parent
1b7bf095dc
commit
fdb2b98a98
@ -1,24 +1,24 @@
|
||||
package com.yunan.controller;
|
||||
|
||||
import com.yunan.constant.ResponseCode;
|
||||
import com.yunan.dto.ApiResponse;
|
||||
import com.yunan.response.ApiResponse;
|
||||
import com.yunan.dto.LoginDTO;
|
||||
import com.yunan.dto.RegisterDTO;
|
||||
import com.yunan.entity.Mail;
|
||||
import com.yunan.pojo.User;
|
||||
import com.yunan.service.AuthService;
|
||||
import com.yunan.service.EmailService;
|
||||
import com.yunan.util.VerificationCodeUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.validation.Valid;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -52,9 +52,10 @@ public class AuthController {
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
@ApiOperation("用户注册")
|
||||
public ResponseEntity<User> register(@RequestBody RegisterDTO registerDTO) {
|
||||
// return authService.register(registerDTO);
|
||||
return null;
|
||||
public ResponseEntity<Object> register(@RequestBody @Valid RegisterDTO registerDTO) throws MessagingException, UnsupportedEncodingException {
|
||||
//获取发送的验证码
|
||||
String rightCode = emailCodeMap.get(registerDTO.getEmail());
|
||||
return authService.register(registerDTO, rightCode);
|
||||
}
|
||||
|
||||
// 存储已发送的验证码
|
||||
@ -62,23 +63,24 @@ public class AuthController {
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
* @param mail
|
||||
* @param registerDTO
|
||||
* @return {@link ApiResponse }<{@link String }>
|
||||
* @throws MessagingException
|
||||
*/
|
||||
@PostMapping("/sendEmail")
|
||||
@ApiOperation("邮箱验证码")
|
||||
public ApiResponse<String> sendEmail(@RequestBody Mail mail) throws MessagingException {
|
||||
public ApiResponse<String> sendEmail(@RequestBody @Valid RegisterDTO registerDTO) throws MessagingException {
|
||||
// 生成验证码
|
||||
String code = VerificationCodeUtils.generateCode(6);
|
||||
|
||||
// 发送邮件
|
||||
String subject = "注册验证码";
|
||||
String content = "尊敬的用户,您的验证码为:" + code;
|
||||
emailService.sendMail(mail.email, subject, content);
|
||||
|
||||
emailService.sendMail(registerDTO.getEmail(), subject, content);
|
||||
|
||||
// 保存验证码
|
||||
emailCodeMap.put(mail.email, code);
|
||||
emailCodeMap.put(registerDTO.getEmail(), code);
|
||||
|
||||
return new ApiResponse<>(ResponseCode.SUCCESS,"验证码已发送");
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
package com.yunan.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Mail {
|
||||
public String email;
|
||||
public String username;
|
||||
public String password;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.yunan.handler;
|
||||
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
// 捕获所有的校验异常
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
|
||||
Map<String, String> errors = new HashMap<>();
|
||||
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
|
||||
errors.put(error.getField(), error.getDefaultMessage());
|
||||
}
|
||||
return ResponseEntity.badRequest().body(errors);
|
||||
}
|
||||
}
|
@ -7,7 +7,5 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface AuthMapper extends BaseMapper<User> {
|
||||
void insertUser(RegisterDTO registerDTO);
|
||||
|
||||
User findUserByEmail(String email);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.yunan.dto;
|
||||
package com.yunan.response;
|
||||
|
||||
|
||||
public class ApiResponse<T> {
|
@ -0,0 +1,48 @@
|
||||
package com.yunan.response;
|
||||
|
||||
// ErrorResponse.java
|
||||
public class ErrorResponse {
|
||||
private String message; // 错误消息
|
||||
private int code; // 错误代码 (可选)
|
||||
private long timestamp; // 错误发生的时间戳 (可选)
|
||||
|
||||
// 构造方法
|
||||
public ErrorResponse(String message) {
|
||||
this.message = message;
|
||||
this.timestamp = System.currentTimeMillis(); // 当前时间戳
|
||||
this.code = 400; // 默认为 400 错误代码
|
||||
}
|
||||
|
||||
// 构造方法(带自定义错误码)
|
||||
public ErrorResponse(String message, int code) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Getter 和 Setter
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
package com.yunan.service;
|
||||
|
||||
|
||||
import com.yunan.dto.ApiResponse;
|
||||
import com.yunan.dto.RegisterDTO;
|
||||
import com.yunan.entity.Mail;
|
||||
import com.yunan.pojo.User;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.AddressException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public interface AuthService {
|
||||
|
||||
|
||||
User register(RegisterDTO registerDTO) throws AddressException, UnsupportedEncodingException;
|
||||
|
||||
ResponseEntity<Object> register(RegisterDTO registerDTO, String rightCode) throws UnsupportedEncodingException, AddressException, MessagingException;
|
||||
}
|
||||
|
@ -1,43 +1,14 @@
|
||||
package com.yunan.service;
|
||||
|
||||
|
||||
import com.yunan.dto.ApiResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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;
|
||||
|
||||
@Service
|
||||
public class EmailService {
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
public interface EmailService {
|
||||
|
||||
@Value("${spring.mail.username}")
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
*
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容
|
||||
*/
|
||||
public void sendMail(String to, String subject, String content) throws MessagingException {
|
||||
// 创建邮件消息
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(content, true);
|
||||
|
||||
// 发送邮件
|
||||
mailSender.send(message);
|
||||
}
|
||||
void sendMail(String email, String subject, String content) throws MessagingException;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,27 +1,17 @@
|
||||
package com.yunan.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.yunan.constant.ResponseCode;
|
||||
import com.yunan.dto.ApiResponse;
|
||||
import com.yunan.dto.RegisterDTO;
|
||||
import com.yunan.mapper.AuthMapper;
|
||||
import com.yunan.pojo.User;
|
||||
import com.yunan.response.ErrorResponse;
|
||||
import com.yunan.service.AuthService;
|
||||
import com.yunan.util.VerificationCodeUtils;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
@Service
|
||||
@ -30,95 +20,39 @@ public class AuthServiceImpl implements AuthService {
|
||||
private AuthMapper authMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Resource
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
/**
|
||||
* 发送邮箱验证码
|
||||
*
|
||||
* @param email
|
||||
* @return {@link String }
|
||||
*/
|
||||
public String sendEmail(@PathVariable String email) throws UnsupportedEncodingException, AddressException {
|
||||
String key = "msg_" + email;
|
||||
|
||||
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
|
||||
String already_have = (String) valueOperations.get(key);
|
||||
if (already_have == null) {
|
||||
// 随机生成一个6位数字型的字符串
|
||||
String code = "123456";
|
||||
// 邮件对象
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setSubject("医院小程序邮箱验证码");
|
||||
message.setText("尊敬的用户您好!\n\n感谢您使用XX医院。\n\n尊敬的: " + email + "您的校验验证码为: " + code + ",有效期2分钟,请不要把验证码信息泄露给其他人,如非本人请勿操作");
|
||||
message.setTo(email);
|
||||
// 对方看到的发送人
|
||||
message.setFrom(new InternetAddress(MimeUtility.encodeText("医院官方") + "<2774668116@qq.com>").toString());
|
||||
//发送邮件
|
||||
mailSender.send(message);
|
||||
valueOperations.set(key, code, 5L, TimeUnit.MINUTES);
|
||||
return code;
|
||||
} else {
|
||||
return already_have;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码验证是否正确
|
||||
* @param email
|
||||
* @param code
|
||||
* @return {@link Integer }
|
||||
*/
|
||||
public Integer verifyCode(String email, String code) {
|
||||
int result = 1;
|
||||
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
|
||||
String msgKey = "msg_" + email;
|
||||
Object value = valueOperations.get(msgKey);
|
||||
if(value == null){
|
||||
result = -1;
|
||||
}else if(!code.equals(value)) {
|
||||
result = 0;
|
||||
}
|
||||
// 如果验证码正确,则删除从redis
|
||||
if(result == 1){
|
||||
stringRedisTemplate.delete(msgKey);
|
||||
}
|
||||
/*
|
||||
1 验证码正确
|
||||
0 验证码错误
|
||||
-1 验证码过期
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User register(RegisterDTO registerDTO) throws AddressException, UnsupportedEncodingException {
|
||||
String code = sendEmail(registerDTO.getEmail());
|
||||
Integer result = verifyCode(registerDTO.getEmail(), registerDTO.getCode());
|
||||
public ResponseEntity<Object> register(RegisterDTO registerDTO, String rightCode) {
|
||||
//处理registerDTO对数据为空的逻辑
|
||||
// 验证验证码的正确性
|
||||
if(registerDTO.getCode() == rightCode){
|
||||
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if(result == 1){
|
||||
queryWrapper.eq(User::getUsername, registerDTO.getUsername());
|
||||
Long l = authMapper.selectCount(queryWrapper);
|
||||
if(l == 0){
|
||||
// 插入用户到数据库
|
||||
authMapper.insertUser(registerDTO);
|
||||
// emailServiceImpl.sendEmail(registerDTO.getEmail(), "注册确认", "请点击以下链接进行确认...");
|
||||
|
||||
// 返回注册成功的用户对象(可根据需求返回具体的 User 对象)
|
||||
// LambdaQueryWrapper<User> queryWrapperByEmail = new LambdaQueryWrapper<>();
|
||||
// queryWrapperByEmail.eq(User::getEmai, registerDTO.getEmail());
|
||||
return authMapper.findUserByEmail(registerDTO.getEmail()); // 假设有这个方法来查询用户
|
||||
if(authMapper.selectOne(queryWrapper) != null) {
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.CONFLICT)
|
||||
.body(new ErrorResponse("用户名已存在!!!"));
|
||||
}
|
||||
User user = new User();
|
||||
user.setUsername(registerDTO.getUsername());
|
||||
user.setPassword(registerDTO.getPassword());
|
||||
user.setEmai(registerDTO.getEmail());
|
||||
boolean isSaved = authMapper.insert(user) > 0;
|
||||
if (isSaved) {
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.OK)
|
||||
.body("注册成功!");
|
||||
} else {
|
||||
throw new RuntimeException("用户存在,请重新输入");
|
||||
}
|
||||
} else if (result == -1) { // 验证码过期
|
||||
throw new RuntimeException("验证码已过期,请重新获取"); // 或者定义自定义异常
|
||||
} else { // 验证码错误
|
||||
throw new RuntimeException("验证码错误,请检查后重试"); // 或者定义自定义异常
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.body("数据库存储失败,请稍后重试");
|
||||
}
|
||||
} else{
|
||||
// 如果验证码为空或者与正确的验证码不匹配,返回错误信息
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.BAD_REQUEST) // 设置 HTTP 状态码为 400
|
||||
.body(new ErrorResponse("验证码不正确或已过期")); // 返回自定义的错误消息
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
spring.application.name=YuNan-demo
|
Loading…
Reference in New Issue
Block a user