mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-07-24 02:09:35 +08:00
登录增加限流控制
This commit is contained in:
parent
f9dec16760
commit
81870bd802
32
src/main/java/xyz/playedu/api/caches/UserLoginCache.java
Normal file
32
src/main/java/xyz/playedu/api/caches/UserLoginCache.java
Normal file
@ -0,0 +1,32 @@
|
||||
package xyz.playedu.api.caches;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import xyz.playedu.api.exception.LimitException;
|
||||
import xyz.playedu.api.util.RedisUtil;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
* @create 2023/3/10 14:13
|
||||
*/
|
||||
@Component
|
||||
public class UserLoginCache {
|
||||
|
||||
private final static String keyTemplate = "user-login:%s";
|
||||
|
||||
private final static int expire = 10;//10s
|
||||
|
||||
public void check(String email) throws LimitException {
|
||||
if (RedisUtil.exists(key(email))) {
|
||||
throw new LimitException();
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String email) {
|
||||
RedisUtil.set(key(email), "1", expire);
|
||||
}
|
||||
|
||||
private String key(String email) {
|
||||
return String.format(keyTemplate, email);
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import xyz.playedu.api.exception.LimitException;
|
||||
import xyz.playedu.api.exception.NotFoundException;
|
||||
import xyz.playedu.api.exception.ServiceException;
|
||||
import xyz.playedu.api.types.JsonResponse;
|
||||
@ -66,4 +67,9 @@ public class ExceptionController {
|
||||
return JsonResponse.error(e.getMessage(), 404);
|
||||
}
|
||||
|
||||
@ExceptionHandler(LimitException.class)
|
||||
public JsonResponse serviceExceptionHandler(LimitException e) {
|
||||
return JsonResponse.error("请稍后再试", 429);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,9 +7,11 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import xyz.playedu.api.caches.UserLoginCache;
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.domain.User;
|
||||
import xyz.playedu.api.event.UserLoginEvent;
|
||||
import xyz.playedu.api.exception.LimitException;
|
||||
import xyz.playedu.api.request.frontend.LoginPasswordRequest;
|
||||
import xyz.playedu.api.service.JWTService;
|
||||
import xyz.playedu.api.service.UserService;
|
||||
@ -39,9 +41,15 @@ public class LoginController {
|
||||
@Autowired
|
||||
private ApplicationContext ctx;
|
||||
|
||||
@Autowired
|
||||
private UserLoginCache userLoginCache;
|
||||
|
||||
@PostMapping("/password")
|
||||
public JsonResponse password(@RequestBody @Validated LoginPasswordRequest req) {
|
||||
User user = userService.find(req.getEmail());
|
||||
public JsonResponse password(@RequestBody @Validated LoginPasswordRequest req) throws LimitException {
|
||||
String email = req.getEmail();
|
||||
userLoginCache.check(email);
|
||||
|
||||
User user = userService.find(email);
|
||||
if (user == null) {
|
||||
return JsonResponse.error("邮箱未注册");
|
||||
}
|
||||
@ -55,7 +63,7 @@ public class LoginController {
|
||||
data.put("token", token.getToken());
|
||||
data.put("expired", token.getExpire());
|
||||
|
||||
ctx.publishEvent(new UserLoginEvent(this, user.getId(), new Date(), token.getToken(), IpUtil.getIpAddress(), RequestUtil.ua()));
|
||||
ctx.publishEvent(new UserLoginEvent(this, user.getId(), user.getEmail(), new Date(), token.getToken(), IpUtil.getIpAddress(), RequestUtil.ua()));
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ public class UserLoginEvent extends ApplicationEvent {
|
||||
|
||||
private Integer userId;
|
||||
|
||||
private String email;
|
||||
|
||||
private Date loginAt;
|
||||
|
||||
private String token;
|
||||
@ -25,9 +27,10 @@ public class UserLoginEvent extends ApplicationEvent {
|
||||
|
||||
private UserAgent userAgent;
|
||||
|
||||
public UserLoginEvent(Object source, Integer userId, Date loginAt, String token, String ip, UserAgent userAgent) {
|
||||
public UserLoginEvent(Object source, Integer userId,String email, Date loginAt, String token, String ip, UserAgent userAgent) {
|
||||
super(source);
|
||||
this.userId = userId;
|
||||
this.email = email;
|
||||
this.loginAt = loginAt;
|
||||
this.token = token;
|
||||
this.ip = ip;
|
||||
|
26
src/main/java/xyz/playedu/api/exception/LimitException.java
Normal file
26
src/main/java/xyz/playedu/api/exception/LimitException.java
Normal file
@ -0,0 +1,26 @@
|
||||
package xyz.playedu.api.exception;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
* @create 2023/3/10 14:13
|
||||
*/
|
||||
public class LimitException extends Exception {
|
||||
public LimitException() {
|
||||
}
|
||||
|
||||
public LimitException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LimitException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public LimitException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public LimitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import xyz.playedu.api.caches.UserLoginCache;
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.event.UserLoginEvent;
|
||||
import xyz.playedu.api.exception.JwtLogoutException;
|
||||
@ -27,6 +28,9 @@ public class UserLoginListener {
|
||||
@Autowired
|
||||
private JWTService jwtService;
|
||||
|
||||
@Autowired
|
||||
private UserLoginCache userLoginCache;
|
||||
|
||||
@EventListener
|
||||
@Async
|
||||
public void updateLoginInfo(UserLoginEvent event) throws JwtLogoutException {
|
||||
@ -44,4 +48,9 @@ public class UserLoginListener {
|
||||
);
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void writeCache(UserLoginEvent event) {
|
||||
userLoginCache.put(event.getEmail());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import xyz.playedu.api.config.PlayEduConfig;
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
|
||||
import java.util.*;
|
||||
|
Loading…
x
Reference in New Issue
Block a user