gpt4 book ai didi

java - 我可以从 spring bean 访问 graphql-context 吗?

转载 作者:行者123 更新时间:2023-12-02 09:29:25 25 4
gpt4 key购买 nike

我们将 spqr graphQl 与 Spring 结合使用。它效果很好并且简化了很多,谢谢!现在我们使用 ResolverInterceptor 进行授权:从 DefaultGlobalContext 读取 JWT token 并进行验证。我们还可以根据此 token 确定当前用户名。所以现在我的问题是:我可以将此用户名存储在 spring bean 中吗? spring bean 和上下文之间有什么联系吗?我们现在要做的是将 DefaultGlobalContext 作为 @GraphQLRootContext 注入(inject)到 @GraphQLApi 的每个方法中,并以这种方式获取用户。如果我们可以只读取一次、将其存储在某个地方并可以在 Spring 托管服务中进行访问,那就更好了。有谁知道这是怎么做到的吗?提前致谢,马蒂亚斯

最佳答案

您可以做一些事情。

<强>1。自定义ArgumentInjector

最简单的方法(也是我推荐的方法)是连接自定义的 ArgumentInjector。您可以使其对某些注释或仅按类型使用react。例如

@Query
public Book book(String id, @LoggedIn User user) {...}

还有一个像这样的注入(inject)器:

public UserInjector implement ArgumentInjector {
@Override
public Object getArgumentValue(ArgumentInjectorParams params) {
ResolutionEnvironment env = params.getResolutionEnvironment();
return extractUserFromRootContext(env.rootContext);
}

@Override
public boolean supports(AnnotatedType type, Parameter parameter) {
//You can also check type.getType().equals(User.class), but IMHO explicit is always better
return parameter != null && parameter.isAnnotationPresent(LoggedIn.class);
}
}

<强>2。自定义 GraphQLExecutor 和请求范围的 bean

另一种方法是使用一个 @RequestScoped bean,将其注入(inject)到 GraphQLExecutor@GraphQLApi 类中。

@Component
//implements GraphQLServletExecutor
public class CustomGraphQLExecutor extends DefaultGraphQLExecutor {

//This is @RequestScoped
private UserHolder userHolder;

@Autowired
public CustomGraphQLExecutor(
ServletContextFactory contextFactory,
Optional<DataLoaderRegistryFactory> registryFactory,
UserHolder userHolder) {

super(contextFactory, registryFactory.orElse(null));
this.userHolder = userHolder;
}

@Override
public Map<String, Object> execute(GraphQL graphQL, GraphQLRequest graphQLRequest, NativeWebRequest nativeRequest) {
userHolder.setUser(getUserFromTheRequest(nativeRequest));
return super.execute(graphQL, graphQLRequest, nativeRequest);
}
}

@Service
@GraphQLApi
public class BookService {

@Autowired
private UserHolder userHolder; //@RequestScoped

@Query
public Book book(String id) {
//Access userHolder as needed
...
}
}

我不喜欢这种方法,因为它创建了对 ThreadLocal 的不可见依赖。如果在任何时候你开始使你的解析器异步(这对于 graphql-java 来说很可能),你将需要特殊包装的线程池,否则事情将根本无法工作。 (此外,如果您转向 WebFlux,它可能根本不起作用,因为 graphql-java 不支持 Reactor,并且无法传播上下文)。

<强>3。使用 Spring Security

由于您所做的只是基本的 Spring Security 内容,因此只需使用它为您提供的功能即可。它与请求范围的 bean 方法具有相同的问题,但您至少不必自己做任何事情。 Spring 已经为您提供了从任何地方访问 SecurityContext 的权限。如果您自定义 Controller 类,还可以将 Principal/Authentication 直接注入(inject) Controller 方法中。

关于java - 我可以从 spring bean 访问 graphql-context 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58101153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com