如何在HotChocolate自定义授权属性中返回未授权响应结果
HotChocolate自定义授权属性返回未授权结果的解决方案
首先纠正一个核心实现误区:ObjectFieldDescriptorAttribute的OnConfigure方法仅在HotChocolate构建Schema阶段执行一次,不会在每次接口请求时触发,因此不能将请求级的授权校验逻辑写在该方法内。
正确的实现方式是通过IObjectFieldDescriptor注册字段执行中间件,将校验逻辑放到每次请求都会触发的中间件中,校验失败时直接构造GraphQL错误返回即可,完整代码如下:
namespace GraphQL.Attributes { public class AuthorizeAttribute : ObjectFieldDescriptorAttribute { public override void OnConfigure(IDescriptorContext context, IObjectFieldDescriptor descriptor, MemberInfo member) { // 注册字段执行中间件,每次请求该字段时都会执行 descriptor.Use(next => async context => { var httpContextAccessor = context.Services.GetRequiredService<IHttpContextAccessor>(); var authorizationHeader = httpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString(); var jwtService = context.Services.GetRequiredService<JwtService>(); var isValidToken = jwtService.ValidateSessionToken(authorizationHeader); if (!isValidToken) { // 构造自定义错误,直接赋值给Result即可终止后续所有执行逻辑 context.Result = ErrorBuilder.New() .SetMessage("Invalid token") .SetCode("401") .SetExtension("Code", 1) .Build(); return; } // 校验通过,继续执行后续字段解析逻辑 await next(context); }); } } }
你也可以选择抛出GraphQLRequestException实现同样的效果:
throw new GraphQLRequestException(ErrorBuilder.New() .SetMessage("Invalid token") .SetCode("401") .SetExtension("Code", 1) .Build());
注意事项
- 必须提前在DI容器中注册
IHttpContextAccessor,注册代码为builder.Services.AddHttpContextAccessor(); - 自定义的
JwtService也需要注册到DI容器中,确保可以被正确解析 - 如果需要全局生效的授权校验,不需要给每个字段加属性,直接在配置GraphQL服务时添加全局中间件即可:
builder.Services.AddGraphQLServer() .UseField(next => async context => { // 全局授权逻辑写在这里 await next(context); });
内容的提问来源于stack exchange,提问作者Slamdunk
相关产品推荐
相关产品推荐

