验证码发送
This commit is contained in:
parent
fea726f2ed
commit
89fdab1864
8
pom.xml
8
pom.xml
|
@ -66,6 +66,14 @@
|
|||
<artifactId>java-jwt</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package com.example.config;
|
||||
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
|
||||
@Configuration
|
||||
public class RabbitConfiguration {
|
||||
@Bean("emailQueue")
|
||||
public Queue emailQueue(){
|
||||
return QueueBuilder
|
||||
.durable("mail")
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.example.controller;
|
||||
|
||||
import com.example.entity.RestBean;
|
||||
import com.example.service.AccountService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/auth")
|
||||
public class AuthorizeController {
|
||||
|
||||
@Resource
|
||||
AccountService service;
|
||||
@GetMapping("/ask-code")
|
||||
public RestBean<Void> askVerifyCode(@RequestParam String email,
|
||||
@RequestParam String type ,
|
||||
HttpServletRequest request){
|
||||
String message = service.registerEmailVerityCode(type , email , request.getRemoteAddr());
|
||||
return message == null ? RestBean.success() : RestBean.failure(400 , message);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
version: '3'
|
||||
services:
|
||||
nginx:
|
||||
image: nginx
|
||||
ports:
|
||||
- 8888:80
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 3
|
||||
visualizer:
|
||||
image: dockersamples/visualizer
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.repo == manager]
|
||||
portainer:
|
||||
image: portainer/portainer
|
||||
ports:
|
||||
- 9000:9000
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
|
@ -0,0 +1,46 @@
|
|||
package com.example.listener;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@RabbitListener(queues = "mail")
|
||||
public class MailQueueListener {
|
||||
@Resource
|
||||
JavaMailSender sender;
|
||||
|
||||
@Value("${spring.mail.username}")
|
||||
String username;
|
||||
|
||||
@RabbitHandler
|
||||
public void sendMailMessage(Map<String , Object> data){
|
||||
String email = (String) data.get("email");
|
||||
Integer code = (Integer) data.get("code");
|
||||
String type = (String) data.get("type");
|
||||
SimpleMailMessage message = switch (type) {
|
||||
case "register" -> createMessage("欢迎注册我们的网站" ,
|
||||
"您的邮件注册验证码为:" + code + ",有效时间三分钟,为了保障您的安全 , 请勿向他人泄漏验证码信息.", email);
|
||||
case "reset" -> createMessage("你的密码重置邮件" ,
|
||||
"你好,您正在进行重置密码操作,验证码:" + code + ", 有效时间三分钟,如非本人操作,请无视." ,email);
|
||||
default -> null;
|
||||
};
|
||||
if (message == null) return;
|
||||
sender.send(message);
|
||||
}
|
||||
|
||||
private SimpleMailMessage createMessage(String title , String content , String email){
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setSubject(title);
|
||||
message.setText(content);
|
||||
message.setTo(email);
|
||||
message.setFrom(username);
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -7,4 +7,5 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||
|
||||
public interface AccountService extends IService<Account> , UserDetailsService {
|
||||
public Account findAccountByNameOrEmail(String text);
|
||||
String registerEmailVerityCode(String type , String email , String ip);
|
||||
}
|
||||
|
|
|
@ -4,14 +4,32 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||
import com.example.entity.dto.Account;
|
||||
import com.example.mapper.AccountMapper;
|
||||
import com.example.service.AccountService;
|
||||
import com.example.utils.Const;
|
||||
import com.example.utils.FlowUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class AccountServiceImpl extends ServiceImpl<AccountMapper , Account> implements AccountService {
|
||||
|
||||
@Resource
|
||||
FlowUtils utils;
|
||||
@Resource
|
||||
AmqpTemplate amqpTemplate;
|
||||
|
||||
@Resource
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
Account account = this.findAccountByNameOrEmail(username);
|
||||
|
@ -24,10 +42,34 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper , Account> imp
|
|||
.build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String registerEmailVerityCode(String type, String email, String ip) {
|
||||
synchronized (ip.intern()){
|
||||
if (this.verifyLimit(ip)){
|
||||
return "请求频繁,请稍后再试";
|
||||
}
|
||||
Random random = new Random();
|
||||
int code = random.nextInt(899999) + 100000;
|
||||
Map<String , Object> data = Map.of("type" , type , "email", email , "code" , code);
|
||||
amqpTemplate.convertAndSend("mail" , data);
|
||||
stringRedisTemplate.opsForValue()
|
||||
.set(Const.VERIFY_EMAIL_DATA + email ,String.valueOf(code), 3 , TimeUnit.MINUTES );
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Account findAccountByNameOrEmail(String text){
|
||||
return this.query()
|
||||
.eq("username",text).or()
|
||||
.eq("email",text)
|
||||
.one();
|
||||
}
|
||||
|
||||
private boolean verifyLimit(String ip){
|
||||
String key = Const.VERIFY_EMAIL_LIMIT + ip;
|
||||
return utils.limitOnceCheck(key , 60);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package com.example.utils;
|
|||
public class Const {
|
||||
public static final String JWT_BLACK_LIST = "jwt:blacklist:";
|
||||
|
||||
public static final String VERIFY_EMAIL_LIMIT = "verify:email:limit:";
|
||||
public static final String VERIFY_EMAIL_DATA = "verify:email:data:";
|
||||
|
||||
public static final int ORDER_CORS = -102;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.example.utils;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class FlowUtils {
|
||||
@Resource
|
||||
StringRedisTemplate template;
|
||||
|
||||
public boolean limitOnceCheck(String key , int blockTime){
|
||||
if (Boolean.TRUE.equals(template.hasKey(key))){
|
||||
return false;
|
||||
}else {
|
||||
template.opsForValue().set(key , "" , blockTime , TimeUnit.SECONDS);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,15 @@
|
|||
|
||||
spring:
|
||||
mail:
|
||||
host: smtp.163.com
|
||||
username: realmeamadeus@163.com
|
||||
password: SFTIRQAPGTZJFEPY
|
||||
rabbitmq:
|
||||
addresses: 8.138.140.94
|
||||
username: rabbitmq
|
||||
password: rabbitmq_Ek=hv-W0
|
||||
virtual-host: /
|
||||
port: 5672
|
||||
security:
|
||||
filter:
|
||||
order: -100 #默认值为-100
|
||||
|
|
Loading…
Reference in New Issue