如何在Spring WebGraphQlInterceptor中提前返回,不执行控制器处理器?
在WebGraphQlInterceptor中实现授权失败时直接终止请求链
完全可以通过WebGraphQlInterceptor实现授权失败时跳过控制器执行,直接返回错误响应,关键是不调用chain.next(request),直接构造合法的响应返回。以下是最简单的实现方式:
核心实现代码
@Component public class AuthorizationInterceptor implements WebGraphQlInterceptor { @Override public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) { // 1. 获取授权所需的HTTP头和GraphQL变量 HttpHeaders requestHeaders = request.getHeaders(); Map<String, Object> graphqlVariables = request.getVariables(); // 2. 执行授权校验逻辑 if (!isRequestAuthorized(requestHeaders, graphqlVariables)) { // 3. 构造GraphQL错误响应,直接返回,终止请求链 GraphQLError authError = GraphqlErrorBuilder.newError() .message("您没有访问该资源的权限") .errorType(ErrorType.UNAUTHORIZED) .build(); return Mono.just(WebGraphQlResponse.builder(request) .errors(List.of(authError)) .build()); } // 授权通过,继续执行原请求链(调用控制器) return chain.next(request); } private boolean isRequestAuthorized(HttpHeaders headers, Map<String, Object> variables) { // 这里替换为你的实际授权逻辑: // 示例:校验请求头中的Token,结合GraphQL变量中的资源ID判断权限 String authToken = headers.getFirst("Authorization"); String targetResourceId = (String) variables.get("resourceId"); return isValidToken(authToken) && hasAccessToResource(authToken, targetResourceId); } // 模拟Token有效性校验 private boolean isValidToken(String token) { return token != null && token.startsWith("Bearer "); } // 模拟资源权限检查 private boolean hasAccessToResource(String token, String resourceId) { // 实际逻辑:根据Token解析用户信息,判断是否有权限访问指定资源 return "user-resource-001".equals(resourceId); } }
关键说明
- 跳过请求链的核心:当授权失败时,直接返回构造好的
WebGraphQlResponse,不调用chain.next(request)——这会直接终止后续的请求处理流程,控制器代码不会被执行。 - 规范构造响应:使用Spring提供的
WebGraphQlResponse.builder(request)是官方推荐的方式,基于当前请求构建合法的响应对象,不存在“不规范”或额外开销的问题。 - 符合GraphQL错误规范:通过
GraphqlErrorBuilder构造的错误会包含标准的错误类型(如UNAUTHORIZED),客户端可以正确识别并处理。
为什么之前的写法会执行控制器
你之前的代码先调用了chain.next(request),这会触发控制器的执行,后续的map只是对控制器返回的响应做修改,所以必须等控制器执行完成才能返回错误。而上面的实现是在执行控制器之前就完成授权校验,直接返回错误,从根源上跳过了控制器的执行。
内容的提问来源于stack exchange,提问作者thatWiseGuy
相关产品推荐
相关产品推荐

