node.js - 关于与 apollo-server 一起使用时如何处理 'graphql-redis-subscriptions' 身份验证的任何想法

标签 node.js graphql apollo-server graphql-subscriptions

我正在使用 https://github.com/davidyaha/graphql-redis-subscriptions 中的“graphql-redis-subscriptions” 。 给出了有关如何设置订阅的几个示例,它们实际上有效,但我面临的问题是如何进行身份验证并允许订阅仅由登录的客户端用户收听。我使用 Apollo-server 来提供 graphql api,如下所示:

const server = new ApolloServer({
            schema,
            dataSources,
            context: async ({ req, connection }) => {
                if (connection) {
                    return {
                        ...connection.context
                    };
                }

                const token = req.headers[API_TOKEN];

                return {
                    premiumAuth: token
                };
            },
        });
        server.listen(5000);

最佳答案

apollo-servercontext选项中进行Authenticated用于HTTP协议(protocol)请求认证。这意味着它将保护 /graphql 端点免受未经身份验证的访问。例如

  const contextFunction: ContextFunction<IContextFunctionParams, IConnectors<IMemoryDB>> = (
    context: IContextFunctionParams,
  ): Context<IAppContext> => {
    const { req, connection } = context;
    if (connection) {
      return connection.context;
    } else {
      const token: string = validateToken(req);
      const userConnector = new UserConnector<IMemoryDB>(memoryDB);
      let user: IUser | undefined;
      try {
        const userType: UserType = UserType[token];
        user = userConnector.findUserByUserType(userType);
      } catch (error) {
        throw error;
      }
      return {
        requestingUser: user,
        locationConnector: new LocationConnector<IMemoryDB>(memoryDB),
        userConnector,
        templateConnector: new TemplateConnector<IMemoryDB>(
          memoryDB,
          pubsub,
          // postgresPubSub,
        ),
      };
    }
  };

用于WebSocket协议(protocol)连接,graphql订阅所依赖。 您需要在 subscriptions.onConnect 方法内进行身份验证,例如

const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: contextFunction,
    introspection: true,
    subscriptions: {
      onConnect: (
        connectionParams: IWebSocketConnectionParams,
        webSocket: WebSocket,
        connectionContext: ConnectionContext,
      ) => {
        console.log('websocket connect');
        console.log('connectionParams: ', connectionParams);
        if (connectionParams.token) {
          const token: string = validateToken(connectionParams.token);
          const userConnector = new UserConnector<IMemoryDB>(memoryDB);
          let user: IUser | undefined;
          try {
            const userType: UserType = UserType[token];
            user = userConnector.findUserByUserType(userType);
          } catch (error) {
            throw error;
          }

          const context: ISubscriptionContext = {
            // pubsub: postgresPubSub,
            pubsub,
            subscribeUser: user,
            userConnector,
            locationConnector: new LocationConnector<IMemoryDB>(memoryDB),
          };

          return context;
        }

        throw new Error('Missing auth token!');
      },
      onDisconnect: (webSocket: WebSocket, connectionContext: ConnectionContext) => {
        console.log('websocket disconnect');
      },
    },
  });

源代码:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/subscriptions

关于node.js - 关于与 apollo-server 一起使用时如何处理 'graphql-redis-subscriptions' 身份验证的任何想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60291238/

相关文章:

javascript - graphql 中突变后的查询

amazon-web-services - AWS AppSync 授权

node.js - 如何在 GraphQL 模式中使用 'Decimal' 作为字段类型?

javascript - 如何更新 nodejs 中的全部或大部分 JSON 值?

node.js - 如何使用拦截器访问 nestjs 中的最终 GraphQL-Response

node.js - 模拟请求对象不适用于 Node.js 中的测试

javascript - 测试扩展类时的 ES6 基类( super 方法)的 Jest 模拟方法

node.js - Sequelize 包含关联不起作用(graphql)

mysql - Node js mysql 实时跟踪数据库表变化

javascript - ECS6 如何在类中定义/创建新对象