From efeabfc2385532f4609d6b8b6ac8b3257078fd89 Mon Sep 17 00:00:00 2001 From: tortoise <2891138827@qq.com> Date: Mon, 12 Aug 2024 14:35:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E4=BC=9A=E6=B5=8B=E9=82=A3=E4=B8=AAap?= =?UTF-8?q?ifox=E6=9C=89token=E6=80=8E=E4=B9=88=E5=8A=A0=E8=BF=9B=E5=8E=BB?= =?UTF-8?q?=E5=95=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 ++ .../top/suyiiyii/sims/common/AuthAccess.java | 17 +++++ .../sims/common/InterceptorConfig.java | 32 ++++++++ .../suyiiyii/sims/common/JwtInterceptor.java | 76 +++++++++++++++++++ .../sims/controller/UserController.java | 4 + .../java/top/suyiiyii/sims/entity/User.java | 5 +- .../suyiiyii/sims/service/UserService.java | 3 + .../top/suyiiyii/sims/utils/TokenUtils.java | 65 ++++++++++++++++ 8 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 src/main/java/top/suyiiyii/sims/common/AuthAccess.java create mode 100644 src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java create mode 100644 src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java create mode 100644 src/main/java/top/suyiiyii/sims/utils/TokenUtils.java diff --git a/pom.xml b/pom.xml index a3164f8..cbf3047 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,11 @@ spring-boot-configuration-processor true + + com.auth0 + java-jwt + 4.2.1 + org.projectlombok lombok diff --git a/src/main/java/top/suyiiyii/sims/common/AuthAccess.java b/src/main/java/top/suyiiyii/sims/common/AuthAccess.java new file mode 100644 index 0000000..65ad38f --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/common/AuthAccess.java @@ -0,0 +1,17 @@ +package top.suyiiyii.sims.common; + +import java.lang.annotation.*; + +/** + * @Author tortoise + * @Date 2024/8/12 11:26 + * @PackageName:top.suyiiyii.sims.common + * @ClassName: AuthAccess + * @Description: TODO + * @Version 1.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AuthAccess { +} diff --git a/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java b/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java new file mode 100644 index 0000000..f9cfade --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java @@ -0,0 +1,32 @@ +package top.suyiiyii.sims.common; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; + +/** + * @Author tortoise + * @Date 2024/8/12 11:27 + * @PackageName:top.suyiiyii.sims.common + * @ClassName: InterceptorConfig + * @Description: TODO 拦截器配置 + * @Version 1.0 + */ + @Configuration + public class InterceptorConfig extends WebMvcConfigurationSupport { + @Override + protected void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(jwtInterceptor()) + .addPathPatterns("/**") + .excludePathPatterns("/login"); // 排除不需要验证的路径 + super.addInterceptors(registry); + } + + @Bean + public JwtInterceptor jwtInterceptor() { + return new JwtInterceptor(); + } + + } + diff --git a/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java b/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java new file mode 100644 index 0000000..f9ed6b4 --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java @@ -0,0 +1,76 @@ +package top.suyiiyii.sims.common; + +import cn.hutool.core.util.StrUtil; +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import top.suyiiyii.sims.entity.User; +import top.suyiiyii.sims.exception.ServiceException; +import top.suyiiyii.sims.mapper.UserMapper; + +/** + * @Author tortoise + * @Date 2024/8/12 11:33 + * @PackageName:top.suyiiyii.sims.common + * @ClassName: JwtInterceptor + * @Description: TODO + * @Version 1.0 + */ + +public class JwtInterceptor implements HandlerInterceptor { + + @Resource + UserMapper userMapper; + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + // 从 Authorization 头中获取 token + String token = request.getHeader("Authorization"); + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); // 去除 "Bearer " 前缀 + } else { + // 如果 Authorization 头中没有 token,则尝试从请求参数中获取 + token = request.getParameter("token"); + } + + // 如果不是映射到方法直接通过 + if (handler instanceof HandlerMethod) { + AuthAccess annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthAccess.class); + if (annotation != null) { + return true; + } + } + + // 执行认证 + if (StrUtil.isBlank(token)) { + throw new ServiceException("401", "请登录");//权限错误 + } + + // 获取 token 中的 user id + String userId; + try { + userId = JWT.decode(token).getAudience().get(0); + } catch (JWTDecodeException j) { + throw new ServiceException("401", "请登录"); + } + + User user = userMapper.selectByUserId(Integer.parseInt(userId)); + if (user == null) { + throw new ServiceException("401", "请登录"); + } + JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();//加密,认证 +//jwtVerifier 验证器 + try { + jwtVerifier.verify(token); + } catch (JWTDecodeException e) { + + throw new ServiceException("401", "请登录"); + } + return true; + } +} diff --git a/src/main/java/top/suyiiyii/sims/controller/UserController.java b/src/main/java/top/suyiiyii/sims/controller/UserController.java index 4bb3127..5d96d04 100644 --- a/src/main/java/top/suyiiyii/sims/controller/UserController.java +++ b/src/main/java/top/suyiiyii/sims/controller/UserController.java @@ -3,6 +3,7 @@ package top.suyiiyii.sims.controller; import cn.hutool.core.util.StrUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import top.suyiiyii.sims.common.AuthAccess; import top.suyiiyii.sims.common.Result; import top.suyiiyii.sims.entity.User; import top.suyiiyii.sims.exception.ServiceException; @@ -24,6 +25,7 @@ import java.util.List; public class UserController { @Autowired UserService userService; +@AuthAccess @GetMapping("/") public Result hello(){ @@ -42,6 +44,7 @@ public class UserController { return Result.success(user); } + @PostMapping("/register") public Result register(@RequestBody User user){ if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){ @@ -58,6 +61,7 @@ public class UserController { } + @GetMapping("/selectAll") public Result selectAll() { List users = userService.selectAll(); diff --git a/src/main/java/top/suyiiyii/sims/entity/User.java b/src/main/java/top/suyiiyii/sims/entity/User.java index 6bf6cce..145aa0f 100644 --- a/src/main/java/top/suyiiyii/sims/entity/User.java +++ b/src/main/java/top/suyiiyii/sims/entity/User.java @@ -17,7 +17,7 @@ import lombok.NoArgsConstructor; * @Version 1.0 */ @Data -@Table +/*@Table*/ @AllArgsConstructor @NoArgsConstructor public class User { @@ -29,5 +29,6 @@ public class User { private String name; private String email; private String group; - + @TableField(exist = false) + private String token; } diff --git a/src/main/java/top/suyiiyii/sims/service/UserService.java b/src/main/java/top/suyiiyii/sims/service/UserService.java index 28a0aef..0c1e98c 100644 --- a/src/main/java/top/suyiiyii/sims/service/UserService.java +++ b/src/main/java/top/suyiiyii/sims/service/UserService.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Service; import top.suyiiyii.sims.entity.User; import top.suyiiyii.sims.exception.ServiceException; import top.suyiiyii.sims.mapper.UserMapper; +import top.suyiiyii.sims.utils.TokenUtils; import java.util.List; @@ -53,6 +54,8 @@ public class UserService { if (!dbUser.getPassword().equals(user.getPassword())) { throw new ServiceException("密码或用户名错误"); } + String token = TokenUtils.createToken(dbUser.getId().toString(), dbUser.getPassword()); + dbUser.setToken(token); return dbUser; } diff --git a/src/main/java/top/suyiiyii/sims/utils/TokenUtils.java b/src/main/java/top/suyiiyii/sims/utils/TokenUtils.java new file mode 100644 index 0000000..e8326b0 --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/utils/TokenUtils.java @@ -0,0 +1,65 @@ +package top.suyiiyii.sims.utils; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import top.suyiiyii.sims.entity.User; +import top.suyiiyii.sims.mapper.UserMapper; + +import java.util.Date; + +/** + * @Author tortoise + * @Date 2024/8/12 11:44 + * @PackageName:top.suyiiyii.sims.utils + * @ClassName: TokenUtils + * @Description: TODO + * @Version 1.0 + */ +@Component +public class TokenUtils{ + private static UserMapper staticUserMapper; + @Resource + UserMapper userMapper; + @PostConstruct + public void setUserService() { + staticUserMapper=userMapper; + } + + /** + * @author: tortoise + * @date: 2024/8/1 15:12 + * @Description: 生成token + * @param userId + * @param sign + * @return: java.lang.String + */ + public static String createToken(String userId, String sign) { + return JWT.create().withAudience(userId) + .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) + .sign(Algorithm.HMAC256(sign)); + + } + public static User getCurrentUser() { + try { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String token = request.getHeader("token"); + if (StrUtil.isBlank(token)) { + + String userId = JWT.decode(token).getAudience().get(0); + return staticUserMapper.selectById(Integer.valueOf(userId)); + } + } catch (Exception e) { + return null; + } + return null; + } + +}