feat: 添加代码格式化
This commit is contained in:
@@ -7,7 +7,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@EnableFeignClients(basePackages = "cn.meowrain.aioj.backend.auth.clients")
|
||||
@SpringBootApplication
|
||||
public class AIOJAuthApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJAuthApplication.class, args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJAuthApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = "user-service", path = "/api/v1/user")
|
||||
public interface UserClient {
|
||||
@GetMapping("/inner/get-by-username")
|
||||
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
||||
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
|
||||
@GetMapping("/inner/get-by-username")
|
||||
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
||||
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cn.meowrain.aioj.backend.auth.common.constants;
|
||||
|
||||
public class RedisKeyConstants {
|
||||
public static String REFRESH_TOKEN_KEY_PREFIX = "refresh_token:%s";
|
||||
|
||||
public static String REFRESH_TOKEN_KEY_PREFIX = "refresh_token:%s";
|
||||
|
||||
}
|
||||
|
||||
@@ -5,16 +5,18 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum ChainMarkEnums {
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,33 +15,27 @@ import org.springframework.security.web.SecurityFilterChain;
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(
|
||||
"/v1/auth/**",
|
||||
"/doc.html",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-resources/**",
|
||||
"/webjars/**",
|
||||
"/v3/api-docs/**",
|
||||
"/favicon.ico"
|
||||
)
|
||||
.permitAll()
|
||||
.anyRequest().authenticated());
|
||||
return http.build();
|
||||
}
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/v1/auth/**", "/doc.html", "/swagger-ui/**", "/swagger-resources/**", "/webjars/**",
|
||||
"/v3/api-docs/**", "/favicon.ico")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
|
||||
return configuration.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
|
||||
return configuration.getAuthenticationManager();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,23 +16,25 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
@EnableKnife4j
|
||||
public class SwaggerConfiguration implements ApplicationRunner {
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("AIOJ-renz微服务✨")
|
||||
.description("用户认证功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI().info(new Info().title("AIOJ-renz微服务✨")
|
||||
.description("用户认证功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,18 +8,22 @@ import org.springframework.stereotype.Component;
|
||||
@Data
|
||||
@ConfigurationProperties(value = JwtPropertiesConfiguration.PREFIX)
|
||||
public class JwtPropertiesConfiguration {
|
||||
public static final String PREFIX = "jwt";
|
||||
/**
|
||||
* JWT 密钥(必须 32 字节以上)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 过期时间(单位:毫秒)
|
||||
*/
|
||||
private long accessExpire; // access token TTL
|
||||
/**
|
||||
* 刷新令牌时间
|
||||
*/
|
||||
private long refreshExpire; // refresh token TTL
|
||||
public static final String PREFIX = "jwt";
|
||||
|
||||
/**
|
||||
* JWT 密钥(必须 32 字节以上)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 过期时间(单位:毫秒)
|
||||
*/
|
||||
private long accessExpire; // access token TTL
|
||||
|
||||
/**
|
||||
* 刷新令牌时间
|
||||
*/
|
||||
private long refreshExpire; // refresh token TTL
|
||||
|
||||
}
|
||||
|
||||
@@ -13,25 +13,24 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping("/v1/auth")
|
||||
public class AuthController {
|
||||
|
||||
private final AuthService authService;
|
||||
private final AuthService authService;
|
||||
|
||||
@PostMapping("/login")
|
||||
public Result<UserLoginResponseDTO> login(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponse = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponse);
|
||||
@PostMapping("/login")
|
||||
public Result<UserLoginResponseDTO> login(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponse = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponse);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/refresh")
|
||||
public Result<UserLoginResponseDTO> refresh(@RequestParam String refreshToken) {
|
||||
return Results.success(authService.refreshToken(refreshToken));
|
||||
}
|
||||
|
||||
@PostMapping("/auth")
|
||||
public Result<String> auth(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponseDTO.getAccessToken());
|
||||
}
|
||||
@PostMapping("/refresh")
|
||||
public Result<UserLoginResponseDTO> refresh(@RequestParam String refreshToken) {
|
||||
return Results.success(authService.refreshToken(refreshToken));
|
||||
}
|
||||
|
||||
@PostMapping("/auth")
|
||||
public Result<String> auth(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponseDTO.getAccessToken());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,26 +12,28 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserLoginRequestParamVerifyChain implements AbstractChianHandler<UserLoginRequestDTO> {
|
||||
@Override
|
||||
public void handle(UserLoginRequestDTO requestParam) {
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
@Override
|
||||
public void handle(UserLoginRequestDTO requestParam) {
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserLoginRequestParamVerifyContext extends CommonChainContext<UserLoginRequestDTO> {
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
|
||||
private String userAccount;
|
||||
|
||||
private String userPassword;
|
||||
|
||||
}
|
||||
|
||||
@@ -10,59 +10,59 @@ import java.util.Date;
|
||||
@Data
|
||||
public class UserAuthRespDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -7,24 +7,28 @@ import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class UserLoginResponseDTO implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
private String accessToken;
|
||||
private String refreshToken;
|
||||
private Long expire;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String refreshToken;
|
||||
|
||||
private Long expire;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
public class JwtAuthenticationFilter {
|
||||
|
||||
}
|
||||
|
||||
@@ -4,17 +4,19 @@ import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
||||
import cn.meowrain.aioj.backend.auth.dto.resp.UserLoginResponseDTO;
|
||||
|
||||
public interface AuthService {
|
||||
/**
|
||||
* 用户登录
|
||||
* @param request {@link UserLoginRequestDTO}
|
||||
* @return {@link UserLoginResponseDTO}
|
||||
*/
|
||||
UserLoginResponseDTO userLogin(UserLoginRequestDTO request);
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
UserLoginResponseDTO refreshToken(String refreshToken);
|
||||
/**
|
||||
* 用户登录
|
||||
* @param request {@link UserLoginRequestDTO}
|
||||
* @return {@link UserLoginResponseDTO}
|
||||
*/
|
||||
UserLoginResponseDTO userLogin(UserLoginRequestDTO request);
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
UserLoginResponseDTO refreshToken(String refreshToken);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,81 +26,84 @@ import java.util.concurrent.TimeUnit;
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
private final JwtUtil jwtUtil;
|
||||
private final UserLoginRequestParamVerifyContext userLoginRequestParamVerifyContext;
|
||||
private final UserClient userClient;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
private final JwtPropertiesConfiguration jwtPropertiesConfiguration;
|
||||
|
||||
@Override
|
||||
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
||||
// 1.校验
|
||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||
requestParam);
|
||||
// 如果调用user-service失败,那么就说明是系统内部错误
|
||||
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
||||
if (userResp.isFail()) {
|
||||
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResp.getData();
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
if (ObjectUtil.isNull(user)
|
||||
|| !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 生成 JWT
|
||||
String accessToken = jwtUtil.generateAccessToken(user);
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
||||
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
||||
resp.setId(user.getId());
|
||||
resp.setUserAccount(user.getUserAccount());
|
||||
resp.setAccessToken(accessToken);
|
||||
resp.setRefreshToken(refreshToken);
|
||||
private final UserLoginRequestParamVerifyContext userLoginRequestParamVerifyContext;
|
||||
|
||||
// refresh token存入到REDIS里面
|
||||
stringRedisTemplate.opsForValue().set(
|
||||
String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()),
|
||||
refreshToken,
|
||||
jwtPropertiesConfiguration.getRefreshExpire(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
return resp;
|
||||
}
|
||||
private final UserClient userClient;
|
||||
|
||||
/**
|
||||
* 更新access token,使用refresh token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserLoginResponseDTO refreshToken(String refreshToken) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO();
|
||||
if (!jwtUtil.isTokenValid(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已过期");
|
||||
}
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
Long userId = Long.valueOf(jwtUtil.parseClaims(refreshToken).getSubject());
|
||||
private final JwtPropertiesConfiguration jwtPropertiesConfiguration;
|
||||
|
||||
String cacheKey = String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, userId);
|
||||
String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
@Override
|
||||
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
||||
// 1.校验
|
||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||
requestParam);
|
||||
// 如果调用user-service失败,那么就说明是系统内部错误
|
||||
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
||||
if (userResp.isFail()) {
|
||||
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResp.getData();
|
||||
|
||||
if (cacheValue == null || !cacheValue.equals(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已失效");
|
||||
}
|
||||
if (ObjectUtil.isNull(user) || !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 生成 JWT
|
||||
String accessToken = jwtUtil.generateAccessToken(user);
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
||||
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
||||
resp.setId(user.getId());
|
||||
resp.setUserAccount(user.getUserAccount());
|
||||
resp.setAccessToken(accessToken);
|
||||
resp.setRefreshToken(refreshToken);
|
||||
|
||||
// 再次签发新的 Access Token
|
||||
// 此处你需要查用户,拿 userName, role
|
||||
Result<UserAuthRespDTO> userResult = userClient.getUserById(String.valueOf(userId));
|
||||
if (userResult.isFail()) {
|
||||
log.error("通过id查找用户失败:{}", userResult.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResult.getData();
|
||||
String newAccessToken = jwtUtil.generateAccessToken(user);
|
||||
// refresh token存入到REDIS里面
|
||||
stringRedisTemplate.opsForValue()
|
||||
.set(String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()), refreshToken,
|
||||
jwtPropertiesConfiguration.getRefreshExpire(), TimeUnit.MILLISECONDS);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新access token,使用refresh token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserLoginResponseDTO refreshToken(String refreshToken) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO();
|
||||
if (!jwtUtil.isTokenValid(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已过期");
|
||||
}
|
||||
|
||||
Long userId = Long.valueOf(jwtUtil.parseClaims(refreshToken).getSubject());
|
||||
|
||||
String cacheKey = String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, userId);
|
||||
String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
|
||||
if (cacheValue == null || !cacheValue.equals(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已失效");
|
||||
}
|
||||
|
||||
// 再次签发新的 Access Token
|
||||
// 此处你需要查用户,拿 userName, role
|
||||
Result<UserAuthRespDTO> userResult = userClient.getUserById(String.valueOf(userId));
|
||||
if (userResult.isFail()) {
|
||||
log.error("通过id查找用户失败:{}", userResult.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResult.getData();
|
||||
String newAccessToken = jwtUtil.generateAccessToken(user);
|
||||
|
||||
// 设置refresh token和access token
|
||||
userLoginResponseDTO.setRefreshToken(refreshToken);
|
||||
userLoginResponseDTO.setAccessToken(newAccessToken);
|
||||
return userLoginResponseDTO;
|
||||
}
|
||||
|
||||
//设置refresh token和access token
|
||||
userLoginResponseDTO.setRefreshToken(refreshToken);
|
||||
userLoginResponseDTO.setAccessToken(newAccessToken);
|
||||
return userLoginResponseDTO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,58 +17,56 @@ import java.util.Map;
|
||||
@Component
|
||||
public class JwtUtil {
|
||||
|
||||
private final JwtPropertiesConfiguration jwtConfig;
|
||||
private final JwtPropertiesConfiguration jwtConfig;
|
||||
|
||||
private SecretKey getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes());
|
||||
}
|
||||
private SecretKey getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes());
|
||||
}
|
||||
|
||||
/** 生成 Access Token */
|
||||
public String generateAccessToken(UserAuthRespDTO user) {
|
||||
long now = System.currentTimeMillis();
|
||||
/** 生成 Access Token */
|
||||
public String generateAccessToken(UserAuthRespDTO user) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", user.getId());
|
||||
claims.put("userName", user.getUserName());
|
||||
claims.put("role", user.getUserRole());
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", user.getId());
|
||||
claims.put("userName", user.getUserName());
|
||||
claims.put("role", user.getUserRole());
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(user.getUserAccount())
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getAccessExpire()))
|
||||
.claims(claims)
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
return Jwts.builder()
|
||||
.subject(user.getUserAccount())
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getAccessExpire()))
|
||||
.claims(claims)
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/** 生成 Refresh Token(只含 userId) */
|
||||
public String generateRefreshToken(Long userId) {
|
||||
long now = System.currentTimeMillis();
|
||||
/** 生成 Refresh Token(只含 userId) */
|
||||
public String generateRefreshToken(Long userId) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(String.valueOf(userId))
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getRefreshExpire()))
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
return Jwts.builder()
|
||||
.subject(String.valueOf(userId))
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getRefreshExpire()))
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/** 解析 Token */
|
||||
public Claims parseClaims(String token) {
|
||||
return Jwts.parser()
|
||||
.verifyWith(getSigningKey())
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload();
|
||||
}
|
||||
/** 解析 Token */
|
||||
public Claims parseClaims(String token) {
|
||||
return Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload();
|
||||
}
|
||||
|
||||
/** 校验 Token 是否过期 */
|
||||
public boolean isTokenValid(String token) {
|
||||
try {
|
||||
Claims claims = parseClaims(token);
|
||||
return claims.getExpiration().after(new Date());
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验 Token 是否过期 */
|
||||
public boolean isTokenValid(String token) {
|
||||
try {
|
||||
Claims claims = parseClaims(token);
|
||||
return claims.getExpiration().after(new Date());
|
||||
} catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user