网管过滤器,用户id穿透到下游
This commit is contained in:
@@ -3,10 +3,7 @@ package top.crushtj.xiaoyi.auth.controller;
|
|||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog;
|
import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog;
|
||||||
import top.crushtj.framework.common.response.Response;
|
import top.crushtj.framework.common.response.Response;
|
||||||
import top.crushtj.xiaoyi.auth.model.vo.user.UserLoginReqVO;
|
import top.crushtj.xiaoyi.auth.model.vo.user.UserLoginReqVO;
|
||||||
@@ -36,7 +33,7 @@ public class UserController {
|
|||||||
|
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
@ApiOperationLog(description = "用户登出")
|
@ApiOperationLog(description = "用户登出")
|
||||||
public Response<Void> logout() {
|
public Response<Void> logout(@RequestHeader("userId") String userId) {
|
||||||
// todo 实现用户登出逻辑
|
// todo 实现用户登出逻辑
|
||||||
return Response.success();
|
return Response.success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ sa-token:
|
|||||||
token-prefix: Bearer
|
token-prefix: Bearer
|
||||||
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
||||||
timeout: 2592000
|
timeout: 2592000
|
||||||
|
# timeout: 60
|
||||||
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||||
active-timeout: -1
|
active-timeout: -1
|
||||||
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package top.crushtj.xiaoyi.gateway.auth;
|
package top.crushtj.xiaoyi.gateway.auth;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
|
import cn.dev33.satoken.exception.NotPermissionException;
|
||||||
|
import cn.dev33.satoken.exception.NotRoleException;
|
||||||
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
|
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
|
||||||
import cn.dev33.satoken.router.SaRouter;
|
import cn.dev33.satoken.router.SaRouter;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
@@ -30,7 +33,7 @@ public class SaTokenConfigure {
|
|||||||
.notMatch("/auth/verification/code/send") // 排除验证码发送接口
|
.notMatch("/auth/verification/code/send") // 排除验证码发送接口
|
||||||
.check(r -> StpUtil.checkLogin()) // 校验是否登录
|
.check(r -> StpUtil.checkLogin()) // 校验是否登录
|
||||||
;
|
;
|
||||||
SaRouter.match("/auth/**", r -> StpUtil.checkPermission("user"));
|
// SaRouter.match("/auth/user/logout", r -> StpUtil.checkPermission("user"));
|
||||||
// 权限认证 -- 不同模块, 校验不同权限
|
// 权限认证 -- 不同模块, 校验不同权限
|
||||||
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
||||||
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||||
@@ -38,6 +41,15 @@ public class SaTokenConfigure {
|
|||||||
// SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
|
// SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
|
||||||
|
|
||||||
// 更多匹配 ... */
|
// 更多匹配 ... */
|
||||||
|
})
|
||||||
|
.setError(e -> {
|
||||||
|
if (e instanceof NotLoginException) { // 未登录异常
|
||||||
|
throw new NotLoginException(e.getMessage(), null, null);
|
||||||
|
} else if (e instanceof NotPermissionException || e instanceof NotRoleException) { // 权限不足,或不具备角色,统一抛出权限不足异常
|
||||||
|
throw new NotPermissionException(e.getMessage());
|
||||||
|
} else { // 其他异常,则抛出一个运行时异常
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -1,5 +1,7 @@
|
|||||||
package top.crushtj.xiaoyi.gateway.exception;
|
package top.crushtj.xiaoyi.gateway.exception;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
|
import cn.dev33.satoken.exception.NotPermissionException;
|
||||||
import cn.dev33.satoken.exception.SaTokenException;
|
import cn.dev33.satoken.exception.SaTokenException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -43,9 +45,17 @@ public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
|
|||||||
if (ex instanceof SaTokenException) { // Sa-Token 异常
|
if (ex instanceof SaTokenException) { // Sa-Token 异常
|
||||||
// 权限认证失败时,设置 401 状态码
|
// 权限认证失败时,设置 401 状态码
|
||||||
response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||||
|
if (ex instanceof NotLoginException){
|
||||||
// 构建响应结果
|
// 构建响应结果
|
||||||
|
result = Response.failure(ResponseCodeEnum.UNAUTHORIZED.getErrorCode(),
|
||||||
|
ex.getMessage());
|
||||||
|
}else if (ex instanceof NotPermissionException) {
|
||||||
result = Response.failure(ResponseCodeEnum.UNAUTHORIZED.getErrorCode(),
|
result = Response.failure(ResponseCodeEnum.UNAUTHORIZED.getErrorCode(),
|
||||||
ResponseCodeEnum.UNAUTHORIZED.getErrorMessage());
|
ResponseCodeEnum.UNAUTHORIZED.getErrorMessage());
|
||||||
|
} else {
|
||||||
|
result = Response.failure(ResponseCodeEnum.SYSTEM_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
} else { // 其他异常,则统一提示 “系统繁忙” 错误
|
} else { // 其他异常,则统一提示 “系统繁忙” 错误
|
||||||
result = Response.failure(ResponseCodeEnum.SYSTEM_ERROR);
|
result = Response.failure(ResponseCodeEnum.SYSTEM_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package top.crushtj.xiaoyi.gateway.filter;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ayi
|
||||||
|
* @version V1.0
|
||||||
|
* @title AddUserId2HeaderFilter
|
||||||
|
* @date 2026/2/4 15:28
|
||||||
|
* @description 添加用户ID到请求头过滤器
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class AddUserId2HeaderFilter implements GlobalFilter {
|
||||||
|
|
||||||
|
private static final String HEADER_USER_ID = "userId";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
Long userId = null;
|
||||||
|
try {
|
||||||
|
userId = StpUtil.getLoginIdAsLong();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
Long finalUserId = userId;
|
||||||
|
ServerWebExchange newExchange = exchange.mutate()
|
||||||
|
.request(builder -> builder.header(HEADER_USER_ID, String.valueOf(finalUserId)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return chain.filter(newExchange);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ sa-token:
|
|||||||
token-prefix: Bearer
|
token-prefix: Bearer
|
||||||
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
||||||
timeout: 2592000
|
timeout: 2592000
|
||||||
|
# timeout: 60
|
||||||
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||||
active-timeout: -1
|
active-timeout: -1
|
||||||
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
||||||
|
|||||||
Reference in New Issue
Block a user