fix:refreshToken
This commit is contained in:
@@ -12,6 +12,7 @@ public enum Code01UserErrorCode implements BaseErrorCode {
|
|||||||
USER_EXISTS("A1000102", "用户已存在"),
|
USER_EXISTS("A1000102", "用户已存在"),
|
||||||
USER_LOGIN_ERROR("A1000103", "用户登录失败!"),
|
USER_LOGIN_ERROR("A1000103", "用户登录失败!"),
|
||||||
USER_REGISTER_ERROR("1000104", "用户注册失败!"),
|
USER_REGISTER_ERROR("1000104", "用户注册失败!"),
|
||||||
|
REFRESH_TOKEN_NOT_EXISTS("1000105", "refreshToken不匹配")
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String code;
|
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 username;
|
||||||
|
|
||||||
private String token;
|
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.api.TokenApi;
|
||||||
import com.xiang.xservice.auth.api.dto.req.LoginRequest;
|
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.RegisterRequest;
|
||||||
import com.xiang.xservice.auth.api.dto.resp.LoginResp;
|
import com.xiang.xservice.auth.api.dto.resp.LoginResp;
|
||||||
import com.xiang.xservice.auth.api.dto.resp.RegisterResp;
|
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")
|
@PostMapping("/public/user/userRegister")
|
||||||
public Result<RegisterResp> register(@RequestBody @Valid @NotNull(message = "请求参数不能为空") RegisterRequest request) {
|
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.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.xiang.xservice.auth.api.dto.req.LoginRequest;
|
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.RegisterRequest;
|
||||||
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
||||||
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
||||||
@@ -38,4 +39,6 @@ public interface XUserService {
|
|||||||
Boolean setUserRole(UserRoleUpdateRequest request);
|
Boolean setUserRole(UserRoleUpdateRequest request);
|
||||||
|
|
||||||
UserDTO getUserDetail(Long userId);
|
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.Code02RoleErrorCode;
|
||||||
import com.xiang.xservice.auth.api.code.Code03DeptErrorCode;
|
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.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.RegisterRequest;
|
||||||
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
import com.xiang.xservice.auth.api.dto.req.user.UserAddRequest;
|
||||||
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
import com.xiang.xservice.auth.api.dto.req.user.UserDeptUpdateRequest;
|
||||||
@@ -123,6 +124,7 @@ public class XUserServiceImpl implements XUserService {
|
|||||||
LoginResp loginResp = new LoginResp();
|
LoginResp loginResp = new LoginResp();
|
||||||
loginResp.setToken(user.getToken());
|
loginResp.setToken(user.getToken());
|
||||||
loginResp.setUsername(request.getUsername());
|
loginResp.setUsername(request.getUsername());
|
||||||
|
loginResp.setRefreshToken(user.getRefreshToken());
|
||||||
return loginResp;
|
return loginResp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,6 +161,7 @@ public class XUserServiceImpl implements XUserService {
|
|||||||
LoginResp loginResp = new LoginResp();
|
LoginResp loginResp = new LoginResp();
|
||||||
loginResp.setToken(token);
|
loginResp.setToken(token);
|
||||||
loginResp.setUsername(request.getUsername());
|
loginResp.setUsername(request.getUsername());
|
||||||
|
loginResp.setRefreshToken(refreshToken);
|
||||||
// 3. redis缓存token
|
// 3. redis缓存token
|
||||||
redisService.set(RedisConstant.LOGIN_TOKEN + request.getUsername(), token, 3, TimeUnit.HOURS);
|
redisService.set(RedisConstant.LOGIN_TOKEN + request.getUsername(), token, 3, TimeUnit.HOURS);
|
||||||
// 4. db 存储token
|
// 4. db 存储token
|
||||||
@@ -318,4 +321,56 @@ public class XUserServiceImpl implements XUserService {
|
|||||||
}
|
}
|
||||||
return dto;
|
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