如何在NestJS中实现GraphQL Subscription身份认证?
在GraphQL Subscription的onConnect中调用AuthService实现身份认证
要在onConnect回调里调用你的AuthService,核心问题是这个回调不属于NestJS的依赖注入容器管理范畴,没法直接注入服务,得通过Nest的**应用上下文(ApplicationContext)**手动获取服务实例。下面是具体实现步骤:
1. 改用forRootAsync配置GraphQL模块
放弃直接用GraphQLModule.forRoot,改用forRootAsync来注入ApplicationContext,这样就能在配置回调里拿到容器中的服务。
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { AuthService } from './auth/auth.service'; import { ApplicationContext } from '@nestjs/core'; @Module({ imports: [ GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, // 注入ApplicationContext,用于获取AuthService inject: [ApplicationContext], useFactory: (appContext: ApplicationContext) => ({ autoSchemaFile: 'schema.gql', // 你的schema配置 subscriptions: { 'graphql-ws': { onConnect: async (context: any) => { // 从请求头Cookie中提取token(根据你的Cookie键名调整) const cookieStr = context.extra.request.headers.cookie; const token = cookieStr?.split('your_token_key=')[1]; if (!token) { throw new Error('未提供认证Token'); } // 从应用上下文获取AuthService实例 const authService = appContext.get(AuthService); // 调用你的验证方法 const user = await authService.verifyTokenAndFindUser(token); if (!user) { throw new Error('Token无效或用户不存在'); } // 将用户信息挂载到context,后续Resolver可通过@Context()获取 return { user }; }, }, }, }), }), // 其他导入模块 ], }) export class AppModule {}
2. 在Resolver中获取已认证用户
完成上述配置后,订阅Resolver可以通过@Context()装饰器拿到onConnect中返回的用户信息:
import { Resolver, Subscription, Context } from '@nestjs/graphql'; @Resolver() export class NotificationResolver { @Subscription(() => Notification) newNotification(@Context() context: any) { // 这里的context.user就是认证后的用户实例 const currentUser = context.user; // 后续业务逻辑:比如只返回该用户的通知 } }
注意事项
- 确保
AuthService已被正确注册到Nest的模块中(比如在AuthModule的providers里声明,并导出给其他模块使用),否则ApplicationContext无法获取到实例。 - 错误处理要明确:
onConnect中抛出的错误会直接拒绝WebSocket连接,前端会收到对应的错误提示。
内容的提问来源于stack exchange,提问作者Raihan Chowdhory
相关产品推荐
相关产品推荐

