fix:refreshToken
This commit is contained in:
@@ -12,6 +12,7 @@ public enum Code01UserErrorCode implements BaseErrorCode {
|
||||
USER_EXISTS("A1000102", "用户已存在"),
|
||||
USER_LOGIN_ERROR("A1000103", "用户登录失败!"),
|
||||
USER_REGISTER_ERROR("1000104", "用户注册失败!"),
|
||||
REFRESH_TOKEN_NOT_EXISTS("1000105", "refreshToken不匹配")
|
||||
;
|
||||
|
||||
private final String code;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.xiang.xservice.auth.api.dto.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: xiang
|
||||
* @Date: 2026-03-20 13:46
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class RefreshRequest {
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* refresh Token
|
||||
*/
|
||||
private String refreshToken;
|
||||
}
|
||||
@@ -12,4 +12,6 @@ public class LoginResp {
|
||||
private String username;
|
||||
|
||||
private String token;
|
||||
|
||||
private String refreshToken;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.xiang.xservice.auth.server.controller;
|
||||
|
||||
import com.xiang.xservice.auth.api.api.TokenApi;
|
||||
import com.xiang.xservice.auth.api.dto.req.LoginRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RefreshRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RegisterRequest;
|
||||
import com.xiang.xservice.auth.api.dto.resp.LoginResp;
|
||||
import com.xiang.xservice.auth.api.dto.resp.RegisterResp;
|
||||
@@ -41,6 +42,20 @@ public class TokenController implements TokenApi {
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/publish/auth/refresh")
|
||||
public Result<LoginResp> refresh(@RequestBody @NotNull(message = "请求参数不能为空") @Valid RefreshRequest request) {
|
||||
try {
|
||||
LoginResp login = userService.refresh(request);
|
||||
return Result.data(login);
|
||||
} catch (BusinessException e) {
|
||||
log.error("【用户登录】用户登录失败,{}", e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("【用户登录】用户登录失败,{}", e.getMessage(), e);
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/public/user/userRegister")
|
||||
public Result<RegisterResp> register(@RequestBody @Valid @NotNull(message = "请求参数不能为空") RegisterRequest request) {
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.xiang.xservice.auth.service.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.xiang.xservice.auth.api.dto.req.LoginRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RefreshRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RegisterRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
||||
@@ -38,4 +39,6 @@ public interface XUserService {
|
||||
Boolean setUserRole(UserRoleUpdateRequest request);
|
||||
|
||||
UserDTO getUserDetail(Long userId);
|
||||
|
||||
LoginResp refresh(RefreshRequest request);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.xiang.xservice.auth.api.code.Code01UserErrorCode;
|
||||
import com.xiang.xservice.auth.api.code.Code02RoleErrorCode;
|
||||
import com.xiang.xservice.auth.api.code.Code03DeptErrorCode;
|
||||
import com.xiang.xservice.auth.api.dto.req.LoginRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RefreshRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.RegisterRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
||||
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
||||
@@ -123,6 +124,7 @@ public class XUserServiceImpl implements XUserService {
|
||||
LoginResp loginResp = new LoginResp();
|
||||
loginResp.setToken(user.getToken());
|
||||
loginResp.setUsername(request.getUsername());
|
||||
loginResp.setRefreshToken(user.getRefreshToken());
|
||||
return loginResp;
|
||||
}
|
||||
}
|
||||
@@ -159,6 +161,7 @@ public class XUserServiceImpl implements XUserService {
|
||||
LoginResp loginResp = new LoginResp();
|
||||
loginResp.setToken(token);
|
||||
loginResp.setUsername(request.getUsername());
|
||||
loginResp.setRefreshToken(refreshToken);
|
||||
// 3. redis缓存token
|
||||
redisService.set(RedisConstant.LOGIN_TOKEN + request.getUsername(), token, 3, TimeUnit.HOURS);
|
||||
// 4. db 存储token
|
||||
@@ -318,4 +321,56 @@ public class XUserServiceImpl implements XUserService {
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginResp refresh(RefreshRequest request) {
|
||||
XUser user = userMapper.selectByUsername(request.getUsername());
|
||||
if (Objects.isNull(user)) {
|
||||
throw new BusinessException(Code01UserErrorCode.USER_NOT_EXISTS);
|
||||
}
|
||||
if (StringUtils.isBlank(user.getRefreshToken()) || !user.getRefreshToken().equals(request.getRefreshToken())) {
|
||||
throw new BusinessException(Code01UserErrorCode.REFRESH_TOKEN_NOT_EXISTS);
|
||||
}
|
||||
// 校验 refreshToken 是否过期
|
||||
Jwt refreshJwt;
|
||||
try {
|
||||
refreshJwt = jwtDecoder.decode(request.getRefreshToken());
|
||||
} catch (Exception e) {
|
||||
log.error("【刷新token】refreshToken解析失败", e);
|
||||
throw new BusinessException("refreshToken 无效或已过期");
|
||||
}
|
||||
if (Objects.isNull(refreshJwt.getExpiresAt()) || refreshJwt.getExpiresAt().isBefore(Instant.now())) {
|
||||
throw new BusinessException("refreshToken 已过期,请重新登录");
|
||||
}
|
||||
// 查询角色
|
||||
List<String> roleCodes = Lists.newArrayList();
|
||||
List<XUserRole> userRoles = userRoleMapper.getByUserId(user.getId());
|
||||
if (CollectionUtils.isNotEmpty(userRoles)) {
|
||||
List<XRole> roles = roleMapper.getRoleByIds(userRoles.stream().map(XUserRole::getRoleId).collect(Collectors.toList()));
|
||||
if (CollectionUtils.isNotEmpty(roles)) {
|
||||
roleCodes.addAll(roles.stream().map(XRole::getCode).toList());
|
||||
}
|
||||
}
|
||||
// 生成新的 accessToken
|
||||
Instant now = Instant.now();
|
||||
JwtClaimsSet claims = JwtClaimsSet.builder()
|
||||
.issuedAt(now)
|
||||
.expiresAt(now.plus(3, ChronoUnit.HOURS))
|
||||
.claim("userId", user.getId())
|
||||
.claim("tenantId", user.getTenantId())
|
||||
.claim("timestamp", System.currentTimeMillis())
|
||||
.claim("username", request.getUsername())
|
||||
.claim("authorities", roleCodes)
|
||||
.build();
|
||||
String newToken = jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||
// 更新 Redis 和 DB
|
||||
redisService.set(RedisConstant.LOGIN_TOKEN + request.getUsername(), newToken, 3, TimeUnit.HOURS);
|
||||
user.setToken(newToken);
|
||||
userMapper.update(user);
|
||||
LoginResp loginResp = new LoginResp();
|
||||
loginResp.setToken(newToken);
|
||||
loginResp.setUsername(request.getUsername());
|
||||
loginResp.setRefreshToken(request.getRefreshToken());
|
||||
return loginResp;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user