diff --git a/afd.md b/afd.md new file mode 100644 index 0000000000000000000000000000000000000000..4bc45af91ab56203245cc1e72fb8ce2661277dea --- /dev/null +++ b/afd.md @@ -0,0 +1 @@ +fsdafsdfsdf \ 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/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 9ebf6150804a974a47ecd5b630327e08c05ef61a..f63eb382bc48367aaf91e5d42ee4dafecc7c4137 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 @@ -7,4 +7,35 @@ public record CreateUserRequestDTO( String password, String rePassword) { // TODO: 密码校验 + public CreateUserRequestDTO{ + /*chengguoqing添加了校验规则1 + */ + if (password == null || password.length() < 6|| password.length() >22) { + throw new RuntimeException("密码长度6-22"); + } +// xuyihua添加了校验规则2 + // 至少包含一个数字 + if (!password.matches(".*\\d.*")) { + throw new RuntimeException("密码必须包含至少一个数字"); + } +// linyanjing添加了校验规则2 + // 至少包含一个字母 + if (!password.matches(".*[a-zA-Z].*")) { + throw new RuntimeException("密码必须包含至少一个字母"); + } +// zhouxudong添加了校验规则2 + // 不能包含空格 + if (password.contains(" ")) { + throw new RuntimeException("密码不能包含空格"); + } +// zhengbinjie和chengguoqing添加了校验规则2 + // 不能是太简单的密码 + String[] weakPasswords = {"123456", "password", "qwerty", "abc123", "admin"}; + for (String weak : weakPasswords) { + if (password.toLowerCase().contains(weak)) { + throw new RuntimeException("密码过于简单,请选择更复杂的密码"); + } + } + } + } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/config/JwtConfig.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/config/JwtConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..009caeb8c0ced00b1cf4cb760f3dd5dc008c70af --- /dev/null +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/config/JwtConfig.java @@ -0,0 +1,13 @@ +package com.example.user.service.application.config; + +import com.example.user.service.common.utils.JwtUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +//zhengbinjie 添加了注册 +@Configuration +public class JwtConfig { + @Bean + public JwtUtils jwtUtils() { + return new JwtUtils(); + } +} 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 42402695584795cd646ce7f6a299db36bd7700d4..adcf7a4f1cc44401e4b3b6cb238cb9ffa138ce31 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,19 +2,23 @@ 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.utils.JwtUtils; 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.stereotype.Service; +import java.util.Map; + @Slf4j @Service public class UserLoginService implements UserLoginUseCase { @Resource private GetUserByNamePort getUserByNamePort; - + @Resource + private JwtUtils jwtUtils; @Override public String login(UserLoginCommand userLoginCommand) { //验证用户 @@ -29,9 +33,12 @@ public class UserLoginService implements UserLoginUseCase { } //签发token /* + * zhouxudong linyanjing添加了调用接口 todo 封装一个JwtUtil实现jwt签发 token 有效期 5min ,key=123456 ,载荷:{name:user.name,id:user.id,is_super} */ - return "token"; + + Map claims = Map.of("name", user.getName().getValue(), "id", user.getId().getValue()); + return jwtUtils.generateToken(user.getName().getValue(), claims); } } diff --git a/user-service/user-service-bootstrap/pom.xml b/user-service/user-service-bootstrap/pom.xml index b9c3d1736aa399f77d2d0754949fa842f54d63eb..0afde319cbec043fb2980e44f59ff1f30624f497 100644 --- a/user-service/user-service-bootstrap/pom.xml +++ b/user-service/user-service-bootstrap/pom.xml @@ -47,6 +47,21 @@ com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + 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 e21f2d53a0095bf9cb21dd0512b3d9844ce3630c..9b6b30eb51ca76cad64bb241d513954b2a77a72b 100644 --- a/user-service/user-service-bootstrap/src/main/resources/application.properties +++ b/user-service/user-service-bootstrap/src/main/resources/application.properties @@ -1,13 +1,18 @@ server.port=28080 spring.application.name=user-service +jwt.secret-key=5a2d9f8e4c1b3a0d7e5f6c2a9b8d4e1f5a2d9f8e4c1b3a0d7e5f6c2a9b8d4e1f +jwt.expiration-time=300000 +nacos.server.addr=192.168.168.128 +nacos.server.addr.port=8848 + # 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 +spring.cloud.nacos.discovery.server-addr=${nacos.server.addr}:${nacos.server.addr.port} # 注册到 nacos 的指定 namespace,默认为 public spring.cloud.nacos.discovery.namespace=public @@ -17,7 +22,7 @@ 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 +spring.cloud.nacos.config.server-addr=${nacos.server.addr}:${nacos.server.addr.port} # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index a198ef344cf3a0a5610b45ce5633040b2e88222a..543cb122312195aca06218ecedf35eca7acb62ee 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -24,6 +24,21 @@ spring-boot-starter-test test + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/utils/JwtUtils.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/utils/JwtUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c210a4d63af25b53d5711a94b7b4fe6e0e080696 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/utils/JwtUtils.java @@ -0,0 +1,94 @@ +package com.example.user.service.common.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; + +import javax.crypto.SecretKey; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.Map; + +public class JwtUtils { + + + @Value("${jwt.secret-key}") + private String SECRET_KEY; + @Value("${jwt.expiration-time}") + private long EXPIRATION_TIME; + + /** + * zhengbinjie 添加了 generateToken + * @param username 用户名(建议使用真名,方便我们"记住"你) + * @return JWT令牌(小心保管,丢了不赔) + */ + public String generateToken(String username,Map claims) { + Date expirationDate = Date.from( + LocalDateTime.now() + .plusYears(100) + .atZone(ZoneId.systemDefault()) + .toInstant() + ); + SecretKey keys = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + return Jwts.builder() + .setClaims(claims) + .setSubject(username) + .setIssuedAt(new Date()) + .setExpiration(expirationDate) + .signWith(keys, SignatureAlgorithm.HS256) + .compact(); + } + + /** + * chengguoqing 添加了parseToken + * 验证JWT令牌(过程非常严格,请自重) + * @param token JWT令牌 + * @return 验证结果(true表示我们勉强认可你) + */ + public Claims parseToken(String token) { + SecretKey keys = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + return Jwts.parserBuilder() + .setSigningKey(keys) + .build() + .parseClaimsJws(token) + .getBody(); + } + + /**xuyihua 添加了 extractUsername + * 从令牌中提取用户名(需要心灵感应能力) + * @param token JWT令牌 + * @return 用户名(如果猜对了请告诉我) + */ + public String extractUsername(String token) { + SecretKey keys = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + return Jwts.parserBuilder() + .setSigningKey( keys) + .build() + .parseClaimsJws(token) + .getBody() + .getSubject(); + + } + + /** huangzhihang 添加了 isTokenExpired + * 检查令牌是否过期(时间感知能力MAX) + * @param token JWT令牌 + * @return 是否过期(过期了就老实重新登录) + */ + public boolean isTokenExpired(String token) { + SecretKey keys = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + Date expiration = Jwts.parserBuilder() + .setSigningKey( keys) + .build() + .parseClaimsJws(token) + .getBody() + .getExpiration(); + return expiration.before(new Date()); + + } + +} +