From 3ced82e4765e622b3b72aa2c2a70500bac081a08 Mon Sep 17 00:00:00 2001 From: szl_xmut <1241707931@qq.com> Date: Fri, 12 Sep 2025 09:52:39 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(user-service):=20=E5=AE=9E=E7=8E=B0JWT?= =?UTF-8?q?=E4=BB=A4=E7=89=8C=E7=94=9F=E6=88=90=E5=92=8C=E7=BB=99=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=98=AF=E5=90=A6=E6=9C=89?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=9D=83=E9=99=90=E8=BF=99=E4=B8=80=E5=B1=9E?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- .../bridge/GetUserByNameBridge.java | 2 +- .../persistence/convertor/UserConvertor.java | 12 +++++++- .../out/persistence/entity/UserEntity.java | 2 ++ .../application/service/UserLoginService.java | 3 +- user-service/user-service-common/pom.xml | 6 ++++ .../example/user/service/common/JwtUtils.java | 29 +++++++++++++++++++ .../com/example/user/service/domain/User.java | 9 ++++++ .../service/domain/valueobject/isSuper.java | 5 ++++ 8 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java create mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java index 38dc3ea..db376e6 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java @@ -23,7 +23,7 @@ public class GetUserByNameBridge implements GetUserByNamePort { //password不空 log.info("userEntity: {}", userEntity); - User user = UserConvertor.toDomain(userEntity); + User user = UserConvertor.userToLogin(userEntity); log.info("user: {}", user); return user; } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java index 6f79540..0b80183 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java @@ -16,13 +16,23 @@ public class UserConvertor { ); } + public static User userToLogin(UserEntity userEntity) { + return new User( + new UserId(userEntity.getId()), + new UserName(userEntity.getName()), + new isSuper(userEntity.is_super()), + new Password(userEntity.getPassword()) + ); + } + public static UserEntity toEntity(User user) { return new UserEntity( user.getId().getValue(), user.getName().getValue(), user.getAge().getValue(), user.getEmail().getValue(), - user.getPassword().encryptedValue() + user.getPassword().encryptedValue(), + user.getIs_super().getValue() ); } } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java index b64228d..91b4c0b 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java @@ -18,7 +18,9 @@ public class UserEntity { private Integer age; private String email; private String password; + private boolean is_super; public UserEntity(long value, String value1, int value2, String value3) { } + } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java index 4240269..d553ec0 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java @@ -2,6 +2,7 @@ package com.example.user.service.application.service; import com.example.user.service.application.command.UserLoginCommand; import com.example.user.service.application.port.in.UserLoginUseCase; +import com.example.user.service.common.JwtUtils; import com.example.user.service.domain.User; import com.example.user.service.domain.port.GetUserByNamePort; import jakarta.annotation.Resource; @@ -32,6 +33,6 @@ public class UserLoginService implements UserLoginUseCase { todo 封装一个JwtUtil实现jwt签发 token 有效期 5min ,key=123456 ,载荷:{name:user.name,id:user.id,is_super} */ - return "token"; + return JwtUtils.createToken(user.getId().id(),user.getName().username(),user.getIs_super().isSuper()); } } diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index a198ef3..88352db 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -24,6 +24,12 @@ spring-boot-starter-test test + + + com.auth0 + java-jwt + 3.10.3 + diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java new file mode 100644 index 0000000..ba795f9 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java @@ -0,0 +1,29 @@ +package com.example.user.service.common; + + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; + +import java.util.Calendar; + + +public class JwtUtils { + private static final String key = "123456"; + /** + * @author suzhilin + * 创建JWT令牌 + * @param id 用户ID + * @param name 用户名称 + * @param is_super 是否为超级用户 + * @return JWT令牌 + */ + public static String createToken(long id,String name,boolean is_super){ + Calendar instance = Calendar.getInstance(); + instance.add(Calendar.MINUTE,5); + return JWT.create().withClaim("userId",id) + .withClaim("name",name) + .withClaim("is_super",is_super) + .withExpiresAt(instance.getTime()) + .sign(Algorithm.HMAC256(key)); + } +} diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index 88945ed..2aa0cb0 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -21,6 +21,7 @@ public class User { private UserAge age; private Email email; private Password password; + private isSuper is_super; public User() { } @@ -48,6 +49,13 @@ public class User { this.email = email; } + public User(UserId id, UserName name,isSuper is_super,Password password) { + this.id = id; + this.is_super = is_super; + this.name = name; + this.password = password; + } + public static List getUsers(GetUserListPort getUserListPort){ return getUserListPort.getUsers(); @@ -79,4 +87,5 @@ public class User { public boolean validatePassword(String password){ return this.password.verify( password); } + } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java new file mode 100644 index 0000000..e79dc20 --- /dev/null +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java @@ -0,0 +1,5 @@ +package com.example.user.service.domain.valueobject; + +public record isSuper(boolean isSuper) { + public boolean getValue(){return isSuper;} +} -- Gitee From 689fa868e278ceb9008b71bb690d50b0bc16c7f5 Mon Sep 17 00:00:00 2001 From: little_jin <861165942@qq.com> Date: Fri, 12 Sep 2025 11:43:39 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix(User):=20=E7=BB=99createUser=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86isSuper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/in/web/controller/UserController.java | 1 + .../user/adapter/in/web/dto/CreateUserRequestDTO.java | 3 ++- .../out/persistence/convertor/UserConvertor.java | 5 +++-- .../adapter/out/persistence/entity/UserEntity.java | 2 +- .../service/application/command/CreateUserCommand.java | 3 ++- .../service/application/service/CreateUserService.java | 8 +++----- .../java/com/example/user/service/domain/User.java | 10 ++++++---- .../domain/valueobject/{isSuper.java => IsSuper.java} | 2 +- 8 files changed, 19 insertions(+), 15 deletions(-) rename user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/{isSuper.java => IsSuper.java} (71%) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 544dd4c..a5063ca 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -56,6 +56,7 @@ public class UserController { .age(createUserRequestDTO.age()) .email(createUserRequestDTO.email()) .password(createUserRequestDTO.password()) + .isSuper(createUserRequestDTO.isSuper()) .build(); return createUserUseCase.createUser(command); diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java index 9ebf615..5318253 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -5,6 +5,7 @@ public record CreateUserRequestDTO( Integer age, String email, String password, - String rePassword) { + String rePassword, + boolean isSuper) { // TODO: 密码校验 } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java index 0b80183..62749dd 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java @@ -12,7 +12,8 @@ public class UserConvertor { new UserName(userEntity.getName()), new UserAge(userEntity.getAge()), new Email(userEntity.getEmail()), - new Password(userEntity.getPassword()) + new Password(userEntity.getPassword()), + new IsSuper(userEntity.isSuper()) ); } @@ -20,7 +21,7 @@ public class UserConvertor { return new User( new UserId(userEntity.getId()), new UserName(userEntity.getName()), - new isSuper(userEntity.is_super()), + new IsSuper(userEntity.isSuper()), new Password(userEntity.getPassword()) ); } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java index 91b4c0b..b44b359 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java @@ -18,7 +18,7 @@ public class UserEntity { private Integer age; private String email; private String password; - private boolean is_super; + private boolean isSuper; public UserEntity(long value, String value1, int value2, String value3) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java index d7f3519..3434410 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java @@ -8,6 +8,7 @@ public record CreateUserCommand( String name, Integer age, String email, - String password + String password, + boolean isSuper ) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java index 931828a..64a87dd 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java @@ -4,10 +4,7 @@ import com.example.user.service.application.command.CreateUserCommand; import com.example.user.service.application.port.in.CreateUserUseCase; import com.example.user.service.domain.User; import com.example.user.service.domain.port.CreateUserPort; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.Password; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserName; +import com.example.user.service.domain.valueobject.*; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -25,7 +22,8 @@ public class CreateUserService implements CreateUserUseCase { new UserAge(createUserCommand.age()), new Email(createUserCommand.email()), // new Password( createUserCommand.password()) - Password.fromRaw(createUserCommand.password()) + Password.fromRaw(createUserCommand.password()), + new IsSuper(createUserCommand.isSuper()) ); log.info("user:{}",user); return createUserPort.createUser(user); diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index 2aa0cb0..5b5758f 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -21,25 +21,27 @@ public class User { private UserAge age; private Email email; private Password password; - private isSuper is_super; + private IsSuper is_super; public User() { } - public User(UserId id, UserName name, UserAge age, Email email, Password password) { + public User(UserId id, UserName name, UserAge age, Email email, Password password, IsSuper is_super) { this.id = id; this.name = name; this.age = age; this.email = email; this.password = password; + this.is_super = is_super; } - public User( UserName name, UserAge age, Email email, Password password) { + public User( UserName name, UserAge age, Email email, Password password, IsSuper is_super) { this.id= genId() ; this.name = name; this.age = age; this.email = email; this.password = password; + this.is_super = is_super; } public User(UserId userId, UserName userName, UserAge userAge, Email email) { @@ -49,7 +51,7 @@ public class User { this.email = email; } - public User(UserId id, UserName name,isSuper is_super,Password password) { + public User(UserId id, UserName name, IsSuper is_super, Password password) { this.id = id; this.is_super = is_super; this.name = name; diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/IsSuper.java similarity index 71% rename from user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java rename to user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/IsSuper.java index e79dc20..3e9578f 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/isSuper.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/IsSuper.java @@ -1,5 +1,5 @@ package com.example.user.service.domain.valueobject; -public record isSuper(boolean isSuper) { +public record IsSuper(boolean isSuper) { public boolean getValue(){return isSuper;} } -- Gitee From 7a1dcfe581770dc30fa9c4b0a3dd1092d03f003b Mon Sep 17 00:00:00 2001 From: szl_xmut <1241707931@qq.com> Date: Fri, 12 Sep 2025 12:56:55 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix(User):=20=E6=B7=BB=E5=8A=A0isSuper?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=88=B0=E7=94=A8=E6=88=B7=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- .../adapter/in/web/controller/UserController.java | 2 ++ .../adapter/in/web/dto/UpdateUserRequestDTO.java | 3 ++- .../out/persistence/bridge/UpdateUserBridge.java | 2 +- .../out/persistence/convertor/UserConvertor.java | 11 +++++++++++ .../application/command/UpdateUserCommand.java | 3 ++- .../application/service/UpdateUserService.java | 4 +++- .../java/com/example/user/service/domain/User.java | 14 +++++++++++--- 7 files changed, 32 insertions(+), 7 deletions(-) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index a5063ca..69c12d1 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -76,11 +76,13 @@ public class UserController { */ @PutMapping("") public User updateUser(@RequestBody UpdateUserRequestDTO updateUserRequestDTO){ + UpdateUserCommand command=UpdateUserCommand.builder() .id(updateUserRequestDTO.id()) .name(updateUserRequestDTO.name()) .age(updateUserRequestDTO.age()) .email(updateUserRequestDTO.email()) + .is_super(updateUserRequestDTO.is_super()) .build(); User user = updateUserUseCase.updateUser(command); return user; diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java index d42ae55..c8b60f9 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java @@ -3,5 +3,6 @@ package com.example.user.adapter.in.web.dto; public record UpdateUserRequestDTO(Long id, String name, Integer age, - String email) { + String email, + boolean is_super) { } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java index 231cd5a..890306f 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java @@ -16,7 +16,7 @@ public class UpdateUserBridge implements UpdateUserPort { @Override public User updateUser(User user) { - int result = userMapper.updateById(UserConvertor.toEntity(user)); + int result = userMapper.updateById(UserConvertor.toUpdateEntity(user)); log.info("result:{}",result); return user; } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java index 62749dd..b1d0034 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java @@ -26,6 +26,17 @@ public class UserConvertor { ); } + public static UserEntity toUpdateEntity(User user) { + return new UserEntity( + user.getId().getValue(), + user.getName().getValue(), + user.getAge().getValue(), + user.getEmail().getValue(), + null, //password不在此处更新 + user.getIs_super().getValue() + ); + } + public static UserEntity toEntity(User user) { return new UserEntity( user.getId().getValue(), diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java index 0ef0ed9..b137582 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java @@ -6,5 +6,6 @@ import lombok.Builder; public record UpdateUserCommand(Long id, String name, Integer age, - String email) { + String email, + boolean is_super) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java index 97da325..583c4df 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java @@ -8,6 +8,7 @@ import com.example.user.service.domain.valueobject.Email; import com.example.user.service.domain.valueobject.UserAge; import com.example.user.service.domain.valueobject.UserId; import com.example.user.service.domain.valueobject.UserName; +import com.example.user.service.domain.valueobject.IsSuper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -22,7 +23,8 @@ public class UpdateUserService implements UpdateUserUseCase { new UserId(command.id()), new UserName(command.name()), new UserAge(command.age()), - new Email(command.email())); + new Email(command.email()), + new IsSuper(command.is_super())); return updateUserPort.updateUser(user); } } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index 5b5758f..64e1e71 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -45,9 +45,9 @@ public class User { } public User(UserId userId, UserName userName, UserAge userAge, Email email) { - this.id = id; - this.name = name; - this.age = age; + this.id = userId; + this.name = userName; + this.age = userAge; this.email = email; } @@ -58,6 +58,14 @@ public class User { this.password = password; } + public User(UserId userId, UserName userName, UserAge userAge, Email email, IsSuper isSuper) { + this.id = userId; + this.name = userName; + this.age = userAge; + this.email = email; + this.is_super = isSuper; + } + public static List getUsers(GetUserListPort getUserListPort){ return getUserListPort.getUsers(); -- Gitee From 52175c485be7088ea0f2a040b03ab32053658d53 Mon Sep 17 00:00:00 2001 From: little_jin <861165942@qq.com> Date: Fri, 12 Sep 2025 13:11:42 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat(User):=20=E7=BB=99createUser=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E5=AF=B9=E4=B8=A4=E6=AC=A1=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E4=B8=80=E8=87=B4=E6=80=A7=E7=9A=84=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/in/web/controller/UserController.java | 2 ++ .../user/adapter/in/web/dto/CreateUserRequestDTO.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index a5063ca..9e9cd15 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -51,6 +51,8 @@ public class UserController { @PostMapping() public User createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ + createUserRequestDTO.validatePassword(); + CreateUserCommand command=CreateUserCommand.builder() .name(createUserRequestDTO.name()) .age(createUserRequestDTO.age()) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java index 5318253..f1d166e 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -8,4 +8,10 @@ public record CreateUserRequestDTO( String rePassword, boolean isSuper) { // TODO: 密码校验 + public void validatePassword() { + if (!password.equals(rePassword)) { + throw new IllegalArgumentException("两次输入的密码不一致"); + } + } + } -- Gitee From 5527980001fc3030b770a66dacaadaeff9789bb4 Mon Sep 17 00:00:00 2001 From: szl_xmut <1241707931@qq.com> Date: Tue, 16 Sep 2025 11:47:07 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat(user-service):=20=E6=B7=BB=E5=8A=A0JWT?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E5=92=8C=E5=AE=89=E5=85=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user-adapter-in-web/pom.xml | 6 ++ .../in/web/config/BasicSecurityConfig.java | 87 ++++++++++++++++ .../adapter/in/web/config/SecurityConfig.java | 44 +++++++++ .../in/web/controller/UserController.java | 77 ++++++++++----- .../user/adapter/in/web/dto/Result.java | 52 ++++++++++ .../web/filter/JwtAuthenticationFilter.java | 99 +++++++++++++++++++ .../in/web/service/TokenBlacklistService.java | 76 ++++++++++++++ .../service/CreateUserService.java | 1 + user-service/user-service-common/pom.xml | 23 +++++ .../example/user/service/common/JwtUtils.java | 61 +++++++++++- 10 files changed, 501 insertions(+), 25 deletions(-) create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/SecurityConfig.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/service/TokenBlacklistService.java diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml index b673bee..97b05bc 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml @@ -15,6 +15,12 @@ + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot spring-boot-starter-web diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java new file mode 100644 index 0000000..711340c --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java @@ -0,0 +1,87 @@ +package com.example.user.adapter.in.web.config; + +import com.example.user.adapter.in.web.filter.JwtAuthenticationFilter; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; +import java.util.List; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(prePostEnabled = true) +@RequiredArgsConstructor +public class BasicSecurityConfig { + + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + } + + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOriginPatterns(List.of("*")); + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); + configuration.setAllowedHeaders(List.of("*")); + configuration.setAllowCredentials(true); + configuration.setMaxAge(3600L); + configuration.setExposedHeaders(Arrays.asList("Authorization", "Content-Type")); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource())) + .sessionManagement(session -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ) + .authorizeHttpRequests(authz -> authz + .requestMatchers("/users/login", "/users/register").permitAll() + .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll() + .requestMatchers("/doc.html", "/webjars/**", "/favicon.ico").permitAll() + .requestMatchers("/actuator/**").permitAll() + .requestMatchers("/error").permitAll() + .anyRequest().authenticated() + ) + + .formLogin(AbstractHttpConfigurer::disable) + .logout(AbstractHttpConfigurer::disable) + .httpBasic(AbstractHttpConfigurer::disable) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + .exceptionHandling(exceptions -> exceptions + .authenticationEntryPoint((request, response, authException) -> { + response.setStatus(401); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":401,\"message\":\"未授权访问,请先登录\",\"data\":null}"); + }) + // 访问拒绝处理器,当已认证用户访问没有权限的资源时调用 + .accessDeniedHandler((request, response, accessDeniedException) -> { + response.setStatus(403); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":403,\"message\":\"访问被拒绝,权限不足\",\"data\":null}"); + }) + ); + + return http.build(); + } +} diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/SecurityConfig.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/SecurityConfig.java new file mode 100644 index 0000000..5a0bfa7 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/SecurityConfig.java @@ -0,0 +1,44 @@ +package com.example.user.adapter.in.web.config; + +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserByNamePort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import java.util.Collections; + +@Configuration +@EnableWebSecurity +@Slf4j +public class SecurityConfig { + @Resource + private GetUserByNamePort getUserByNamePort; + @Bean + public UserDetailsService userDetailsService() { + return new UserDetailsService() { + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + log.debug("Loading user by username: {}", username); + User user = User.getUserByName(username,getUserByNamePort); + if (user == null) { + log.warn("User not found: {}", username); + throw new UsernameNotFoundException("用户不存在: " + username); + } + return org.springframework.security.core.userdetails.User.builder() + .username(user.getName().username()) + .password(user.getPassword().encryptedValue()) + .accountExpired(false) + .accountLocked(false) + .credentialsExpired(false) + .build(); + } + }; + } +} diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 44dfbf7..9cb54d2 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -1,16 +1,19 @@ package com.example.user.adapter.in.web.controller; -import com.example.user.adapter.in.web.dto.CreateUserRequestDTO; -import com.example.user.adapter.in.web.dto.UpdateUserRequestDTO; -import com.example.user.adapter.in.web.dto.UserLoginRequestDTO; -import com.example.user.adapter.in.web.dto.UserResponseDTO; +import com.example.user.adapter.in.web.dto.*; +import com.example.user.adapter.in.web.service.TokenBlacklistService; import com.example.user.service.application.command.CreateUserCommand; import com.example.user.service.application.command.UpdateUserCommand; import com.example.user.service.application.command.UserLoginCommand; import com.example.user.service.application.port.in.*; import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserByNamePort; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -27,6 +30,8 @@ public class UserController { private final UpdateUserUseCase updateUserUseCase; private final GetUserByIdUseCase getUserByIdUseCase; private final UserLoginUseCase userLoginUseCase; + private final GetUserByNamePort getUserByNamePort; + private final TokenBlacklistService tokenBlacklistService; @PostMapping("login") @@ -36,8 +41,7 @@ public class UserController { .name(userLoginRequestDTO.getName()) .password(userLoginRequestDTO.getPassword()) .build(); - String token = userLoginUseCase.login(command); - return token; + return userLoginUseCase.login(command); } @@ -48,11 +52,9 @@ public class UserController { return getUserListUseCase.getUsers(); } - @PostMapping() - public User createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ - + @PostMapping("/register") + public Result createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ createUserRequestDTO.validatePassword(); - CreateUserCommand command=CreateUserCommand.builder() .name(createUserRequestDTO.name()) .age(createUserRequestDTO.age()) @@ -60,8 +62,23 @@ public class UserController { .password(createUserRequestDTO.password()) .isSuper(createUserRequestDTO.isSuper()) .build(); - - return createUserUseCase.createUser(command); + try{ + User existingUser = User.getUserByName(createUserRequestDTO.name(),getUserByNamePort); + if (existingUser != null) { + log.warn("注册失败: 用户名已存在 - {}", createUserRequestDTO.name()); + return Result.error("用户名已存在,请选择其他用户名"); + } + User user = createUserUseCase.createUser(command); + if(user != null){ + return Result.success("注册成功",user); + }else { + return Result.error("注册失败,请稍后重试"); + } + }catch (Exception e){ + log.error("用户注册失败: 数据库插入失败 - {}", createUserRequestDTO.name()); + log.info(e.getMessage()); + return Result.error("注册失败,请稍后重试"); + } } @@ -71,11 +88,6 @@ public class UserController { return "success"; } - /** - * @author liuxin - * @param updateUserRequestDTO - * @return - */ @PutMapping("") public User updateUser(@RequestBody UpdateUserRequestDTO updateUserRequestDTO){ @@ -91,11 +103,6 @@ public class UserController { } - /** - * @author dengli - * @param id - * @return - */ @GetMapping("{id}") public UserResponseDTO getUserById(@PathVariable("id") Long id){ User user = getUserByIdUseCase.getUserById(id); @@ -106,4 +113,30 @@ public class UserController { user.getEmail().email()); return userResponseDTO; } + + @PostMapping("/logout") + @Operation(summary = "用户登出", description = "用户登出,清除认证信息并将token加入黑名单") + public Result logout(HttpServletRequest request) { + try { + String token = getJwtFromRequest(request); + if (token != null) { + tokenBlacklistService.addToBlacklist(token); + log.info("Token已加入黑名单: {}", token.substring(0, Math.min(token.length(), 20)) + "..."); + } + SecurityContextHolder.clearContext(); + log.info("用户登出成功"); + return Result.success("登出成功,token已失效"); + } catch (Exception e) { + log.error("用户登出失败: {}", e.getMessage()); + return Result.error("登出失败: " + e.getMessage()); + } + } + + private String getJwtFromRequest(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + return bearerToken.substring(7); + } + return null; + } } diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java new file mode 100644 index 0000000..302c085 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java @@ -0,0 +1,52 @@ +package com.example.user.adapter.in.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Result { + + private Integer code; + + + private String message; + + + private T data; + + public static Result success(T data) { + return new Result<>(200, "操作成功", data); + } + + public static Result success() { + return new Result<>(200, "操作成功", null); + } + + + public static Result success(String message, T data) { + return new Result<>(200, message, data); + } + + + public static Result error(String message) { + return new Result<>(500, message, null); + } + + + public static Result error(Integer code, String message) { + return new Result<>(code, message, null); + } + + + public static Result unauthorized(String message) { + return new Result<>(401, message, null); + } + + + public static Result forbidden(String message) { + return new Result<>(403, message, null); + } +} \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java new file mode 100644 index 0000000..8bc6708 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java @@ -0,0 +1,99 @@ +package com.example.user.adapter.in.web.filter; + +import com.example.user.adapter.in.web.service.TokenBlacklistService; +import com.example.user.service.common.JwtUtils; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Slf4j +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + @Autowired + private JwtUtils jwtUtil; + + @Autowired + private TokenBlacklistService tokenBlacklistService; + + @Autowired + private ApplicationContext applicationContext; + + private UserDetailsService userDetailsService; + + private UserDetailsService getUserDetailsService() { + if (userDetailsService == null) { + userDetailsService = applicationContext.getBean(UserDetailsService.class); + } + return userDetailsService; + } + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + try { + String jwt = getJwtFromRequest(request); + if (StringUtils.hasText(jwt)) { + if (tokenBlacklistService.isBlacklisted(jwt)) { + log.warn("Token is blacklisted (user has logged out): {}", + jwt.substring(0, Math.min(20, jwt.length())) + "..."); + SecurityContextHolder.clearContext(); + filterChain.doFilter(request, response); + return; + } + String username = jwtUtil.getUsernameFromToken(jwt); + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + UserDetails userDetails = getUserDetailsService().loadUserByUsername(username); + if (jwtUtil.validateToken(jwt, userDetails.getUsername())) { + UsernamePasswordAuthenticationToken authentication = + new UsernamePasswordAuthenticationToken( + userDetails, + null, + userDetails.getAuthorities() + ); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authentication); + log.debug("JWT authentication successful for user: {}", username); + } else { + log.warn("JWT token validation failed for user: {}", username); + } + } + } + } catch (Exception e) { + log.error("Cannot set user authentication: {}", e.getMessage()); + SecurityContextHolder.clearContext(); + } + filterChain.doFilter(request, response); + } + + private String getJwtFromRequest(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + return jwtUtil.extractTokenFromHeader(bearerToken); + } + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + String path = request.getRequestURI(); + boolean isBusinessWhitelist = path.startsWith("/users/login") || + path.startsWith("/users/register"); + boolean isDocWhitelist = path.startsWith("/doc.html") || + path.startsWith("/swagger-ui") || + path.startsWith("/v3/api-docs") || + path.startsWith("/webjars"); + return isBusinessWhitelist || isDocWhitelist; + } +} \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/service/TokenBlacklistService.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/service/TokenBlacklistService.java new file mode 100644 index 0000000..d33b8c6 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/service/TokenBlacklistService.java @@ -0,0 +1,76 @@ +package com.example.user.adapter.in.web.service; + +import com.example.user.service.common.JwtUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TokenBlacklistService { + private final JwtUtils jwtUtil; + + private final ConcurrentHashMap blacklistedTokens = new ConcurrentHashMap<>(); + + public void addToBlacklist(String token) { + try { + Date expirationTime = jwtUtil.getExpirationDateFromToken(token); + blacklistedTokens.put(token, expirationTime); + log.info("令牌已添加到黑名单,过期时间: {}, 令牌前缀: {}...", + expirationTime, + token.substring(0, Math.min(token.length(), 10))); + + } catch (Exception e) { + log.warn("添加令牌到黑名单时发生错误: {}, 令牌前缀: {}...", + e.getMessage(), + token.substring(0, Math.min(token.length(), 10))); + } + } + + + public boolean isBlacklisted(String token) { + boolean isBlacklisted = blacklistedTokens.containsKey(token); + + if (isBlacklisted) { + log.debug("检测到黑名单令牌访问尝试,令牌前缀: {}...", + token.substring(0, Math.min(token.length(), 10))); + } + + return isBlacklisted; + } + + @Scheduled(fixedRate = 3600000) // 每小时执行一次 + public void cleanupExpiredTokens() { + Date now = new Date(); + int initialSize = blacklistedTokens.size(); + + blacklistedTokens.entrySet().removeIf(entry -> { + Date expirationTime = entry.getValue(); + return expirationTime != null && now.after(expirationTime); + }); + + int finalSize = blacklistedTokens.size(); + int cleanedCount = initialSize - finalSize; + + if (cleanedCount > 0) { + log.info("黑名单清理完成,清理了 {} 个过期令牌,当前黑名单大小: {}", cleanedCount, finalSize); + } else { + log.debug("黑名单清理完成,无过期令牌需要清理,当前黑名单大小: {}", finalSize); + } + } + + public int getBlacklistSize() { + return blacklistedTokens.size(); + } + + public void clearBlacklist() { + int size = blacklistedTokens.size(); + blacklistedTokens.clear(); + log.warn("黑名单已被清空,共清理了 {} 个令牌", size); + } +} \ No newline at end of file diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java index 64a87dd..74d9f34 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java @@ -16,6 +16,7 @@ public class CreateUserService implements CreateUserUseCase { private CreateUserPort createUserPort; @Override public User createUser(CreateUserCommand createUserCommand) { + log.info(createUserCommand.name()); //command -> domain User user=new User( new UserName(createUserCommand.name()), diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index 88352db..3682827 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -30,6 +30,29 @@ java-jwt 3.10.3 + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + org.projectlombok + lombok + 1.18.38 + diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java index ba795f9..832c18c 100644 --- a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtils.java @@ -3,12 +3,21 @@ package com.example.user.service.common; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import javax.crypto.SecretKey; import java.util.Calendar; +import java.util.Date; - +@Slf4j +@Component public class JwtUtils { - private static final String key = "123456"; + private static final String key = "${jwt.secret:mySecretKeyForJwtTokenGenerationAndValidation123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789}"; /** * @author suzhilin * 创建JWT令牌 @@ -24,6 +33,52 @@ public class JwtUtils { .withClaim("name",name) .withClaim("is_super",is_super) .withExpiresAt(instance.getTime()) - .sign(Algorithm.HMAC256(key)); + .sign(Algorithm.HMAC512(key)); + } + + public String getUsernameFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.get("name",String.class); + } + + private Claims getClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } + + + public boolean validateToken(String token, String username) { + try { + String tokenUsername = getUsernameFromToken(token); + return (username.equals(tokenUsername) && !isTokenExpired(token)); + } catch (Exception e) { + log.error("Token validation failed: {}", e.getMessage()); + return false; + } + } + + public Date getExpirationDateFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.getExpiration(); + } + + private boolean isTokenExpired(String token) { + Date expiration = getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + private SecretKey getSigningKey() { + byte[] keyBytes = key.getBytes(); + return Keys.hmacShaKeyFor(keyBytes); + } + + public String extractTokenFromHeader(String authHeader) { + if (authHeader != null && authHeader.startsWith("Bearer ")) { + return authHeader.substring(7); + } + return null; } } -- Gitee From 12513cf8e5a7405a646da47fe116f5c8088a9524 Mon Sep 17 00:00:00 2001 From: szl_xmut <1241707931@qq.com> Date: Tue, 16 Sep 2025 12:50:14 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix(user-service):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AD=98=E5=9C=A8=E6=80=A7=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=92=8C=E7=A9=BA=E5=80=BC=E5=A4=84=E7=90=86=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=B3=A8=E5=86=8C=E4=B8=8D=E8=83=BD=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/in/web/controller/UserController.java | 2 +- .../adapter/out/persistence/bridge/GetUserByNameBridge.java | 4 +++- .../user/service/application/service/CreateUserService.java | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 9cb54d2..7e4dea9 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -62,8 +62,8 @@ public class UserController { .password(createUserRequestDTO.password()) .isSuper(createUserRequestDTO.isSuper()) .build(); + User existingUser = User.getUserByName(createUserRequestDTO.name(),getUserByNamePort); try{ - User existingUser = User.getUserByName(createUserRequestDTO.name(),getUserByNamePort); if (existingUser != null) { log.warn("注册失败: 用户名已存在 - {}", createUserRequestDTO.name()); return Result.error("用户名已存在,请选择其他用户名"); diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java index db376e6..9666d82 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByNameBridge.java @@ -22,7 +22,9 @@ public class GetUserByNameBridge implements GetUserByNamePort { UserEntity userEntity = userMapper.selectOne(wrapper); //password不空 log.info("userEntity: {}", userEntity); - + if(userEntity == null){ + return null; + } User user = UserConvertor.userToLogin(userEntity); log.info("user: {}", user); return user; diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java index 74d9f34..64a87dd 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java @@ -16,7 +16,6 @@ public class CreateUserService implements CreateUserUseCase { private CreateUserPort createUserPort; @Override public User createUser(CreateUserCommand createUserCommand) { - log.info(createUserCommand.name()); //command -> domain User user=new User( new UserName(createUserCommand.name()), -- Gitee