您觉得本文档还缺少什么内容?可以自己补充~
接口请求流程
每个接口请求时,请求头中都要携带封装了用户身份的token请求头,请求通过网关路由到后端具体的服务,并在网关的系统会将请求头中的token信息解析成用户信息(userId, orgId, name, account 等信息),再次封装到请求头中。
- 大致流程:
- 详细流程:
通过上图可以知道,正常流程中,调用后端请求时,需要在请求头中携带token、tenant等参数,在网关解析并验证token、解码tenant后,将用户id、用户账号、姓名、解码后的tenant等基础信息封装到请求头中,转发请求到具体的 业务服务中,而每个业务服务都有一个上下文拦截器HeaderThreadLocalInterceptor
, 用于将请求头中的用户ID、租户编码等信息封装到LocalThread中。 这样,当请求到达Controller->Service->Mapper 层时,程序就能通过LocalThread获取当前登录人的信息和租户编码用于业务处理了。
如何让请求不携带租户编码(tenant) ?
- 在 bc-gateway-server.yml 中配置:
bc:
ignore:
tenant:
- /aaa/
- /bbb/**
- 实现方式:
public class TokenContextFilter implements WebFilter, Ordered {
private void parseTenant(ServerHttpRequest request, ServerHttpRequest.Builder mutate) {
// NONE模式 直接忽略tenant
if ("NONE".equals(multiTenantType)) {
addHeader(mutate, JWT_KEY_TENANT, "_NONE");
ContextUtil.setTenant("_NONE");
MDC.put(JWT_KEY_TENANT, StrPool.EMPTY);
return;
}
// 使请求忽略验证请求中的 租户编码(tenant) 参数
if (isIgnoreTenant(request.getPath().toString())) {
return;
}
// 后面的代码省略
}
}
- debug TokenContextFilter 过滤器, 配置了的地址只要使得 isIgnoreTenant 方法放回true, 请求就可以不携带租户信息。
private void parseTenant(ServerHttpRequest request, ServerHttpRequest.Builder mutate) {
// 使请求忽略验证请求中的 租户编码(tenant) 参数
if (isIgnoreTenant(request.getPath().toString())) {
return;
}
String tenant = getHeader(TENANT_ID_KEY, request);
if (StrUtil.isNotEmpty(tenant)) {
ContextUtil.setTenantId(tenant);
addHeader(mutate, TENANT_ID_HEADER, ContextUtil.getTenantId());
MDC.put(TENANT_ID_HEADER, tenant);
}
}
- 注意: 配置后,后台接口不能获取租户信息,用户信息,不能校验URI权限
如何让请求不携带用户凭据(token) ?
- 在 bc-gateway-server.yml 中配置:
bc:
ignore:
token:
- /aaa/
- /bbb/**
- 实现方式:
public class TokenContextFilter implements WebFilter, Ordered {
private Mono<Void> parseToken(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
ServerHttpRequest.Builder mutate = request.mutate();
// 判断接口是否需要忽略token验证
if (isIgnoreToken(request.getPath().toString())) {
log.debug("当前接口:{}, 不解析用户token", request.getPath().toString());
return chain.filter(exchange);
}
// 后面的代码省略
}
}
- 注意: 配置后,后台接口不能 不能获取 用户信息,不能校验URI权限
如何让请求不验证URI权限
- 全局禁用, 修改 common.yml : (禁用后,整个系统所有方法,都不需要校验URI权限)
bc:
security:
enabled: false # false = 全局禁用 uri 权限
- 单个控制类禁用: (禁用后,该类下面的所有方法,都不需要校验URI权限)
@PreAuth(replace = "authority:user:", enabled = false)
public class UserController {
// n个方法
}
- 单个控制类中的方法禁用: (禁用后,该方法不需要校验URI权限)
@PreAuth(replace = "authority:user:")
public class UserController {
@PreAuth(enabled = false)
@GetMapping("/check")
public R<Boolean> check(@RequestParam(required = false) Long id, @RequestParam String name) {
return success(baseService.check(id, name));
}
}