From 340924adbbf8520b43518c4aaa58f3063d09b95b Mon Sep 17 00:00:00 2001 From: yeguiyang Date: Thu, 11 Sep 2025 21:42:17 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E5=8C=96=E9=85=8D?= =?UTF-8?q?=E7=BD=AEinit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 5 ++- .../src/main/resources/application.properties | 41 ++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 40fbb78..f5afad7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,7 +13,10 @@ - + + + \ No newline at end of file diff --git a/user-service/user-service-bootstrap/src/main/resources/application.properties b/user-service/user-service-bootstrap/src/main/resources/application.properties index e21f2d5..d08d950 100644 --- a/user-service/user-service-bootstrap/src/main/resources/application.properties +++ b/user-service/user-service-bootstrap/src/main/resources/application.properties @@ -1,24 +1,27 @@ server.port=28080 spring.application.name=user-service +spring.datasource.url=jdbc:mysql://localhost:3306/shixun +spring.datasource.username=root +spring.datasource.password=root +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -# Nacos认证信息 -spring.cloud.nacos.discovery.username=nacos -spring.cloud.nacos.discovery.password=nacos -# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 -spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 -# 注册到 nacos 的指定 namespace,默认为 public -spring.cloud.nacos.discovery.namespace=public - -# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html -# Nacos认证信息 -spring.cloud.nacos.config.username=nacos -spring.cloud.nacos.config.password=nacos -spring.cloud.nacos.config.contextPath=/nacos -# 设置配置中心服务端地址 -spring.cloud.nacos.config.server-addr=192.168.168.128:8848 -# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 -# spring.cloud.nacos.config.namespace= -spring.config.import=nacos:${spring.application.name}.properties?refresh=true +## Nacos认证信息 +#spring.cloud.nacos.discovery.username=nacos +#spring.cloud.nacos.discovery.password=nacos +## Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 +#spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 +## 注册到 nacos 的指定 namespace,默认为 public +#spring.cloud.nacos.discovery.namespace=public +# +## Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html +## Nacos认证信息 +#spring.cloud.nacos.config.username=nacos +#spring.cloud.nacos.config.password=nacos +#spring.cloud.nacos.config.contextPath=/nacos +## 设置配置中心服务端地址 +#spring.cloud.nacos.config.server-addr=192.168.168.128:8848 +## Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 +## spring.cloud.nacos.config.namespace= +#spring.config.import=nacos:${spring.application.name}.properties?refresh=true -- Gitee From 35319b32b49c68ffed6cbdea0a4b1bd4a99b1afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E8=B6=85?= <13409862+li-zeming37@user.noreply.gitee.com> Date: Thu, 11 Sep 2025 22:17:08 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(user-service):=20=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=EF=BC=8CJWT=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- .../in/web/dto/CreateUserRequestDTO.java | 7 +- user-service/user-service-application/pom.xml | 6 ++ .../application/service/UserLoginService.java | 31 +++---- user-service/user-service-common/pom.xml | 25 ++++++ .../example/user/service/common/JwtUtil.java | 81 +++++++++++++++++++ .../service/common/PasswordValidator.java | 30 +++++++ 6 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/PasswordValidator.java 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..d76d82c 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 @@ -1,10 +1,15 @@ package com.example.user.adapter.in.web.dto; +import com.example.user.service.common.PasswordValidator; + public record CreateUserRequestDTO( String name, Integer age, String email, String password, String rePassword) { - // TODO: 密码校验 + // 密码校验 已完成 + public void validate() { + PasswordValidator.validate(this.password, this.rePassword); + } } diff --git a/user-service/user-service-application/pom.xml b/user-service/user-service-application/pom.xml index df05045..209630c 100644 --- a/user-service/user-service-application/pom.xml +++ b/user-service/user-service-application/pom.xml @@ -36,6 +36,12 @@ user-service-domain 0.0.1-SNAPSHOT + + + com.example + user-service-common + 0.0.1-SNAPSHOT + 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..b3268bb 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.JwtUtil; import com.example.user.service.domain.User; import com.example.user.service.domain.port.GetUserByNamePort; import jakarta.annotation.Resource; @@ -15,23 +16,25 @@ public class UserLoginService implements UserLoginUseCase { @Resource private GetUserByNamePort getUserByNamePort; + @Resource + private JwtUtil jwtUtil; // 1. 注入 + @Override - public String login(UserLoginCommand userLoginCommand) { - //验证用户 - User user = User.getUserByName(userLoginCommand.name(), getUserByNamePort); - log.info("user:{}", user); - if(user==null){ + public String login(UserLoginCommand cmd) { + User user = User.getUserByName(cmd.name(), getUserByNamePort); + if (user == null) { throw new RuntimeException("用户不存在"); } - //验证密码 - if(!user.validatePassword(userLoginCommand.password())){ + if (!user.validatePassword(cmd.password())) { throw new RuntimeException("密码错误"); } - //签发token - /* - todo 封装一个JwtUtil实现jwt签发 - token 有效期 5min ,key=123456 ,载荷:{name:user.name,id:user.id,is_super} - */ - return "token"; + + // 2. 把需要的数据塞进 User 对象(仅做载荷,不持久化) + User payload = new User(); + payload.setId(user.getId()); + payload.setName(user.getName()); + + // 3. 签发 + return jwtUtil.generateToken(payload); } -} +} \ No newline at end of file diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index a198ef3..ad8f41e 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -19,6 +19,31 @@ spring-boot-starter + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + com.example + user-service-domain + 0.0.1-SNAPSHOT + + org.springframework.boot spring-boot-starter-test diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java new file mode 100644 index 0000000..d8e75a5 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java @@ -0,0 +1,81 @@ +package com.example.user.service.common; + +import com.example.user.service.domain.User; +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class JwtUtil { + private static final Logger logger= LoggerFactory.getLogger(JwtUtil.class); +@Value("${jwt-secret}") + private String secret; +@Value("${jwt-expiration-milliseconds}") + private long expiration; + public String generateToken(User user){ + Map claims=new HashMap<>(); + //设置负载 + claims.put("User",user); + claims.put("is_uper",1); + //创建token + String token= Jwts.builder() + //设置头部类型和算法 + .setHeaderParam("typ", "JWT") + .setHeaderParam("alg", "HS256") + //加入负载 + .setClaims(claims) + //设置签发时间 + .setIssuedAt(new Date()) + //设置过期时间 + .setExpiration(new Date(System.currentTimeMillis()+expiration)) + //签名 + .signWith(getKey()) + //拼接生成token + .compact(); + return token; + } + private Key getKey(){ + //对密钥进行解码 + return Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret)); + } + //解析token并验证token + public boolean validateToken(String token){ + try { + //创建JWT解析器构建器 + Jwts.parserBuilder() + //设置密钥 + .setSigningKey(getKey()) + .build() + //解析并验证JWT令牌 + .parseClaimsJws(token); + return true; + }catch (MalformedJwtException e) { + logger.error("Invalid JWT token: {}", e.getMessage()); + } catch (ExpiredJwtException e) { + logger.error("JWT token is expired: {}", e.getMessage()); + } catch (UnsupportedJwtException e) { + logger.error("JWT token is unsupported: {}", e.getMessage()); + } catch (IllegalArgumentException e) { + logger.error("JWT claims string is empty: {}", e.getMessage()); + } + return false; + + } + //获得负载 + public Claims getClaims(String token){ + return Jwts.parserBuilder() + .setSigningKey(getKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } +} diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/PasswordValidator.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/PasswordValidator.java new file mode 100644 index 0000000..8f7eeb9 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/PasswordValidator.java @@ -0,0 +1,30 @@ +package com.example.user.service.common; + +public final class PasswordValidator { + + private static final int MIN_LEN = 8; + private static final int MAX_LEN = 32; + + private PasswordValidator() {} + + public static void validate(String password, String rePassword) { + if (password == null || rePassword == null) { + throw new IllegalArgumentException("密码不能为空"); + } + if (!password.equals(rePassword)) { + throw new IllegalArgumentException("两次输入的密码不一致"); + } + if (password.length() < MIN_LEN || password.length() > MAX_LEN) { + throw new IllegalArgumentException("密码长度必须在 " + MIN_LEN + "~" + MAX_LEN + " 位之间"); + } + if (!password.matches(".*[A-Z].*")) { + throw new IllegalArgumentException("密码必须包含至少一个大写字母"); + } + if (!password.matches(".*[a-z].*")) { + throw new IllegalArgumentException("密码必须包含至少一个小写字母"); + } + if (!password.matches(".*[0-9].*")) { + throw new IllegalArgumentException("密码必须包含至少一个数字"); + } + } +} \ No newline at end of file -- Gitee From c92192390740dcb9c2ec11f0f5f060685f2ab6d5 Mon Sep 17 00:00:00 2001 From: yeguiyang Date: Thu, 11 Sep 2025 22:53:26 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(user-service):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=90=AF=E5=8A=A8=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- .../application/service/UserLoginService.java | 9 ++++----- user-service/user-service-bootstrap/pom.xml | 16 ++++++++-------- user-service/user-service-common/pom.xml | 6 ------ .../com/example/user/service/common/JwtUtil.java | 16 +++++++--------- 4 files changed, 19 insertions(+), 28 deletions(-) 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 b3268bb..f1e854f 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 @@ -29,12 +29,11 @@ public class UserLoginService implements UserLoginUseCase { throw new RuntimeException("密码错误"); } - // 2. 把需要的数据塞进 User 对象(仅做载荷,不持久化) - User payload = new User(); - payload.setId(user.getId()); - payload.setName(user.getName()); + // 2. 转化数据 + Long id = user.getId().id(); + String name = user.getName().username(); // 3. 签发 - return jwtUtil.generateToken(payload); + return jwtUtil.generateToken(id, name); } } \ No newline at end of file diff --git a/user-service/user-service-bootstrap/pom.xml b/user-service/user-service-bootstrap/pom.xml index b9c3d17..4ea8c04 100644 --- a/user-service/user-service-bootstrap/pom.xml +++ b/user-service/user-service-bootstrap/pom.xml @@ -38,15 +38,15 @@ 0.0.1-SNAPSHOT - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - + + + + - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - + + + + diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index ad8f41e..2896a46 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -38,12 +38,6 @@ runtime - - com.example - user-service-domain - 0.0.1-SNAPSHOT - - org.springframework.boot spring-boot-starter-test diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java index d8e75a5..c6ea5ef 100644 --- a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java @@ -1,30 +1,28 @@ package com.example.user.service.common; -import com.example.user.service.domain.User; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.security.Key; import java.util.Date; import java.util.HashMap; import java.util.Map; - @Component public class JwtUtil { private static final Logger logger= LoggerFactory.getLogger(JwtUtil.class); -@Value("${jwt-secret}") - private String secret; -@Value("${jwt-expiration-milliseconds}") - private long expiration; - public String generateToken(User user){ +//密钥 + private static final String secret="fGZkYmNjMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY"; +//过期时间 + private static final long expiration= 5 * 60 * 1000; + public String generateToken(Long id,String name){ Map claims=new HashMap<>(); //设置负载 - claims.put("User",user); + claims.put("id",id); + claims.put("name",name); claims.put("is_uper",1); //创建token String token= Jwts.builder() -- Gitee