您觉得本文档还缺少什么内容?可以自己补充~

接口请求流程

每个接口请求时,请求头中都要携带封装了用户身份的token请求头,请求通过网关路由到后端具体的服务,并在网关的系统会将请求头中的token信息解析成用户信息(userId, orgId, name, account 等信息),再次封装到请求头中。

  1. 大致流程:

  1. 详细流程:

通过上图可以知道,正常流程中,调用后端请求时,需要在请求头中携带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));
    }
}

results matching ""

    No results matching ""