From 2c9a880c233baac841cda93c8903ae354632fd3a Mon Sep 17 00:00:00 2001 From: ArgonarioD Date: Wed, 29 Jun 2022 11:32:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BA=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8CRedis=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=8F=96=E6=B6=88=E4=BA=86?= =?UTF-8?q?LoginException=EF=BC=8CPOM=E8=A7=A3=E5=86=B3=E4=BA=86=E7=88=86?= =?UTF-8?q?=E7=BA=A2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + .../advice/ExceptionHandlerAdvice.java | 33 ++++++++++++++ .../projectmanagement/config/RedisConfig.java | 33 ++++++++++++++ .../projectmanagement/config/WebConfig.java | 4 +- .../controller/StaffController.java | 13 ++++-- .../exception/BadRequestException.java | 9 ++++ .../exception/LoginException.java | 9 ---- .../interceptor/CorsInterceptor.java | 6 +-- .../interceptor/TokenInterceptor.java | 9 ++-- .../service/IStaffService.java | 5 +-- .../service/impl/StaffServiceImpl.java | 43 +++++++++---------- .../projectmanagement/utils/TokenUtils.java | 23 ++++++---- .../utils/response/ResponseMap.java | 3 +- .../projectmanagement/MybatisPlusTests.java | 8 ++++ .../rmdjzz/projectmanagement/RedisTests.java | 22 ++++++++++ 15 files changed, 164 insertions(+), 57 deletions(-) create mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java create mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/RedisConfig.java create mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java delete mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/LoginException.java create mode 100644 src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/RedisTests.java diff --git a/pom.xml b/pom.xml index 10f64a0..4520883 100644 --- a/pom.xml +++ b/pom.xml @@ -142,6 +142,7 @@ org.springframework.boot spring-boot-maven-plugin + 2.7.1 diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java new file mode 100644 index 0000000..927ee28 --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java @@ -0,0 +1,33 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.advice; + +import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; +import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException; +import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * @author 佘语殊 + * @since 2022/6/29 1:00 + */ +@Slf4j +@RestControllerAdvice +public class ExceptionHandlerAdvice { + @ExceptionHandler(TokenException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public ResponseMap handleTokenException(TokenException e) { + // log.error(ExceptionUtils.getStackTrace(e)); + log.error(e.getMessage()); + return ResponseMap.of(HttpStatus.UNAUTHORIZED.value(), e.getMessage()); + } + + @ExceptionHandler(BadRequestException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseMap handleBadRequestException(BadRequestException e) { + log.error(e.getMessage()); + return ResponseMap.of(HttpStatus.BAD_REQUEST.value(), e.getMessage()); + } +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/RedisConfig.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/RedisConfig.java new file mode 100644 index 0000000..1e9e476 --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/RedisConfig.java @@ -0,0 +1,33 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; + +import javax.annotation.Resource; + +/** + * @author 佘语殊 + * @since 2022/6/28 17:48 + */ +@Configuration +public class RedisConfig { + + @Resource + RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + template.setKeySerializer(RedisSerializer.json()); + template.setValueSerializer(RedisSerializer.json()); + template.setHashKeySerializer(RedisSerializer.json()); + template.setHashValueSerializer(RedisSerializer.json()); + template.afterPropertiesSet(); + return template; + } + +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/WebConfig.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/WebConfig.java index 619b68b..3f29c6b 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/WebConfig.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/config/WebConfig.java @@ -23,7 +23,9 @@ public class WebConfig implements WebMvcConfigurer { registry.addInterceptor(corsInterceptor).addPathPatterns("/**"); registry.addInterceptor(new TokenInterceptor()) .addPathPatterns("/**") - .excludePathPatterns("/api/login"); + .excludePathPatterns("/staff/login") + .excludePathPatterns("/hello") + .excludePathPatterns("/staff/hello2"); } /* @Override diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java index 2806674..2f4fb13 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java @@ -1,10 +1,9 @@ package cn.edu.hfut.rmdjzz.projectmanagement.controller; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; -import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException; import cn.edu.hfut.rmdjzz.projectmanagement.service.impl.StaffServiceImpl; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; -import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,13 +15,19 @@ import org.springframework.web.bind.annotation.RestController; * created at 2022/6/28 21:59 */ @RestController -@RequestMapping("/api") +@RequestMapping("/staff") public class StaffController { @Autowired private StaffServiceImpl staffServiceImpl; + @SneakyThrows @PostMapping("/login") - public ResponseMap login(@RequestBody Staff staff) throws LoginException, JsonProcessingException { + public ResponseMap login(@RequestBody Staff staff) { return staffServiceImpl.login(staff.getStaffUsername(), staff.getStaffPassword()); } + + @RequestMapping("/hello2") + public ResponseMap hello2(@RequestBody Staff str) { + return ResponseMap.ofSuccess("adada", str); + } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java new file mode 100644 index 0000000..43984ee --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java @@ -0,0 +1,9 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.exception; + +/** + * @author 张韬 + * created at 2022/6/28 21:24 + */ +public class BadRequestException extends Exception{ + public BadRequestException(String message){super(message);} +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/LoginException.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/LoginException.java deleted file mode 100644 index ee32061..0000000 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/LoginException.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.edu.hfut.rmdjzz.projectmanagement.exception; - -/** - * @author 张韬 - * created at 2022/6/28 21:24 - */ -public class LoginException extends Exception{ - public LoginException(String message){super(message);} -} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/CorsInterceptor.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/CorsInterceptor.java index 4647214..69a98df 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/CorsInterceptor.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/CorsInterceptor.java @@ -1,6 +1,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.interceptor; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @@ -18,12 +19,11 @@ public class CorsInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "*"); - response.setHeader("Access-Control-Allow-Headers", "content-type,token"); - response.setHeader("Content-Type", "application/json;charset=utf-8"); + response.setHeader("Access-Control-Allow-Headers", "Content-Type,Token"); response.setHeader("Access-Control-Allow-Credentials","false"); // 如果是OPTIONS则结束请求 if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { - response.setStatus(200); + response.setStatus(HttpStatus.OK.value()); return false; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/TokenInterceptor.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/TokenInterceptor.java index b0d7d25..1be9ba8 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/TokenInterceptor.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/interceptor/TokenInterceptor.java @@ -6,6 +6,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; @@ -20,14 +21,14 @@ import java.io.IOException; * @author 张韬 * created at 2022/6/28 18:16 */ +//FIXME: objectMapper去掉 @Component public class TokenInterceptor implements HandlerInterceptor { - @Resource - private ObjectMapper objectMapper; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws TokenException, IOException { System.out.println(httpServletRequest.getRequestURL()+" "+httpServletRequest.getMethod()); - if (!(object instanceof HandlerMethod)) { + throw new TokenException("in token"); + /*if (!(object instanceof HandlerMethod)) { return false; } String token = httpServletRequest.getHeader("Token"); @@ -47,6 +48,6 @@ public class TokenInterceptor implements HandlerInterceptor { return false; } httpServletResponse.setHeader("Token",TokenUtils.autoRequire(token)); - return true; + return true;*/ } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java index eb30ce4..03c9360 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java @@ -1,15 +1,14 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; -import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException; +import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import com.baomidou.mybatisplus.extension.service.IService; -import com.fasterxml.jackson.core.JsonProcessingException; /** * @author 佘语殊 * @since 2022/6/28 17:28 */ public interface IStaffService extends IService { - ResponseMap login(String username, String password) throws LoginException, JsonProcessingException; + ResponseMap login(String username, String password) throws BadRequestException; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java index 67e607c..af2fdb4 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java @@ -1,7 +1,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service.impl; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; -import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException; +import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.mapper.StaffMapper; import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; @@ -9,13 +9,9 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; -import javax.annotation.Resource; - /** * @author 佘语殊 * @since 2022/6/28 17:29 @@ -24,23 +20,24 @@ import javax.annotation.Resource; public class StaffServiceImpl extends ServiceImpl implements IStaffService { @Override - public ResponseMap login(String username, String password) throws LoginException, JsonProcessingException { - if(username==null||username.trim().length()==0) - throw new LoginException("用户名为空"); - else if(!username.equals(username.replaceAll("[^a-zA-Z0-9]", ""))) - throw new LoginException("用户名格式错误"); - else if(password==null||password.trim().length()!=32) - throw new LoginException("密码格式错误"); - Staff staff = getOne(Wrappers.lambdaQuery().eq(Staff::getStaffUsername,username)); - if(staff==null) - throw new LoginException("用户不存在"); - password= DigestUtils.md5DigestAsHex((password+staff.getStaffSalt()).getBytes()); - if(!staff.getStaffPassword().equals(password)) - throw new LoginException("密码错误"); - ResponseMap res=ResponseMap.ofSuccess("ok").put("username",username); - res.put("Token",TokenUtils.getToken(staff.getStaffUsername(),staff.getStaffId())); - res.put("staffFullname",staff.getStaffFullname()); - res.put("staffId",staff.getStaffId()); - return res; + public ResponseMap login(String username, String password) throws BadRequestException { + if (username == null || username.trim().length() == 0) + throw new BadRequestException("用户名为空"); + else if (!username.equals(username.replaceAll("[^a-zA-Z0-9]", ""))) + throw new BadRequestException("用户名格式错误"); + else if (password == null || password.trim().length() != 32) + throw new BadRequestException("密码格式错误"); + + Staff staff = getOne(Wrappers.lambdaQuery().eq(Staff::getStaffUsername, username)); + if (staff == null) + throw new BadRequestException("用户不存在"); + password = DigestUtils.md5DigestAsHex((password + staff.getStaffSalt()).getBytes()); + if (!staff.getStaffPassword().equals(password)) + throw new BadRequestException("密码错误"); + return ResponseMap.ofSuccess("ok") + .put("Token", TokenUtils.getToken(staff.getStaffUsername(), staff.getStaffId())) + .put("staffUsername", username) + .put("staffFullname", staff.getStaffFullname()) + .put("staffId", staff.getStaffId()); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java index 95e01d2..3de8e7c 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java @@ -15,16 +15,18 @@ import java.util.Date; */ //TODO: 演示的时候把expireTime改短点儿 public final class TokenUtils { - public final static String pvKey="SignedByRMDJZZ"; - public static String getToken(String username,Integer staffId){ + public final static String pvKey = "SignedByRMDJZZ"; + + public static String getToken(String username, Integer staffId) { return JWT.create() .withClaim("username", username) .withClaim("staffId", staffId) .withIssuedAt(new Date()) - .withExpiresAt(new Date(System.currentTimeMillis() + 5*60*60*1000)) + .withExpiresAt(new Date(System.currentTimeMillis() + 5 * 60 * 60 * 1000)) .sign(Algorithm.HMAC256(pvKey)); } + public static boolean checkToken(String token) throws TokenException { JWTVerifier verifier = JWT.require(Algorithm.HMAC256(pvKey)).build(); try { @@ -34,24 +36,29 @@ public final class TokenUtils { throw new TokenException("非法的Token"); } } + public static boolean checkTimeOut(String token) throws TokenException { - if(!checkToken(token)) + if (!checkToken(token)) return true; - return JWT.decode(token).getClaim("exp").asLong()<(System.currentTimeMillis()/1000); + return JWT.decode(token).getClaim("exp").asLong() < (System.currentTimeMillis() / 1000); } + public static String getUsername(String token) throws TokenException { - if(!checkToken(token)) + if (!checkToken(token)) return null; return JWT.decode(token).getClaim("username").asString(); } + public static Integer getStaffId(String token) throws TokenException { - if(!checkToken(token)) + if (!checkToken(token)) return null; return JWT.decode(token).getClaim("staffId").asInt(); } + public static String refreshToken(String token) throws TokenException { - return getToken(getUsername(token),getStaffId(token)); + return getToken(getUsername(token), getStaffId(token)); } + public static String autoRequire(String token) throws TokenException { boolean check = checkToken(token); if (check) { diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java index 7eef933..c4c3873 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java @@ -2,14 +2,12 @@ package cn.edu.hfut.rmdjzz.projectmanagement.utils.response; import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.core.serializer.support.SerializationFailedException; import org.springframework.http.HttpStatus; -import javax.annotation.Resource; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -26,6 +24,7 @@ public class ResponseMap { private Integer code; private String msg; private Map data; + /** * 静态构造方法 * diff --git a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java index 7764c52..2cc51ea 100644 --- a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java +++ b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java @@ -10,6 +10,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; /** * @author 佘语殊 @@ -31,5 +33,11 @@ public class MybatisPlusTests { staffService.getOne(Wrappers.query().last("limit 1")) ) )); + Map map = new HashMap<>(); + map.put("123", "456"); + map.put(894, 789); + System.out.println(objectMapper.writeValueAsString( + ResponseMap.ofSuccess("ok", map) + )); } } diff --git a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/RedisTests.java b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/RedisTests.java new file mode 100644 index 0000000..7c2435d --- /dev/null +++ b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/RedisTests.java @@ -0,0 +1,22 @@ +package cn.edu.hfut.rmdjzz.projectmanagement; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; + +import javax.annotation.Resource; + +/** + * @author 佘语殊 + * @since 2022/6/28 23:10 + */ +@SpringBootTest +public class RedisTests { + @Resource + private RedisTemplate redisTemplate; + + @Test + void test(){ + redisTemplate.opsForList().rightPush(123456,89); + } +}