feat(auth): 实现用户退出登录功能
- 在网关过滤器中增加对未登录异常的处理 - 完善用户登出接口,调用 Sa-Token 的登出方法 - 新增 UserService 中的 logout 方法实现 - 优化获取用户 ID 的逻辑并增强异常处理 - 清理 Sa-Token 上下文避免内存泄漏
This commit is contained in:
@@ -29,8 +29,7 @@ public class UserController {
|
|||||||
@ApiOperationLog(description = "账号登出")
|
@ApiOperationLog(description = "账号登出")
|
||||||
public Response<?> logout(@RequestHeader("userId") String userId) {
|
public Response<?> logout(@RequestHeader("userId") String userId) {
|
||||||
log.info("==> 网关透传过来的用户 ID: {}", userId);
|
log.info("==> 网关透传过来的用户 ID: {}", userId);
|
||||||
// todo 账号退出登录逻辑待实现
|
Long userIdLong = Long.parseLong(userId);
|
||||||
|
return userService.logout(userIdLong);
|
||||||
return Response.success();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,10 @@ public interface UserService extends IService<UserDO> {
|
|||||||
* @return 响应结果
|
* @return 响应结果
|
||||||
*/
|
*/
|
||||||
Response<String> loginAndRegister(UserLoginReqVO reqVO);
|
Response<String> loginAndRegister(UserLoginReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
* @return 响应结果
|
||||||
|
*/
|
||||||
|
Response<?> logout(Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,4 +142,10 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<?> logout(Long userId) {
|
||||||
|
StpUtil.logout(userId);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.hanserwei.hannote.gateway.filter;
|
package com.hanserwei.hannote.gateway.filter;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
|
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
@@ -19,20 +21,25 @@ public class AddUserId2HeaderFilter implements GlobalFilter {
|
|||||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
log.info("==================> TokenConvertFilter");
|
log.info("==================> TokenConvertFilter");
|
||||||
// 用户 ID
|
// 用户 ID
|
||||||
Long userId = null;
|
Long userId;
|
||||||
|
SaReactorSyncHolder.setContext(exchange);
|
||||||
try {
|
try {
|
||||||
// 获取当前登录用户的 ID
|
// 获取当前登录用户的 ID
|
||||||
userId = StpUtil.getLoginIdAsLong();
|
userId = StpUtil.getLoginIdAsLong();
|
||||||
} catch (Exception e) {
|
} catch (NotLoginException e) {
|
||||||
log.error("==> 用户未登录, 获取用户 ID 失败: ", e);
|
log.debug("==> 用户未登录, 不追加 userId 请求头");
|
||||||
// 若没有登录,则直接放行
|
|
||||||
return chain.filter(exchange);
|
return chain.filter(exchange);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("==> 获取用户 ID 失败", e);
|
||||||
|
return chain.filter(exchange);
|
||||||
|
} finally {
|
||||||
|
SaReactorSyncHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("## 当前登录的用户 ID: {}", userId);
|
log.info("## 当前登录的用户 ID: {}", userId);
|
||||||
Long finalUserId = userId;
|
|
||||||
ServerWebExchange newExchange = exchange.mutate()
|
ServerWebExchange newExchange = exchange.mutate()
|
||||||
.request(builder -> builder.header(HEADER_USER_ID, String.valueOf(finalUserId))) // 将用户 ID 设置到请求头中
|
.request(builder -> builder.headers(headers -> headers.set(HEADER_USER_ID, String.valueOf(userId)))) // 将用户 ID 设置到请求头中
|
||||||
.build();
|
.build();
|
||||||
return chain.filter(newExchange);
|
return chain.filter(newExchange);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user