You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:32:12