Любая идея о том, как обрабатывать аутентификацию graphql-redis-subscription при использовании вместе с apollo-server - PullRequest
1 голос
/ 19 февраля 2020

Я использую 'graphql-redis-subscription' из https://github.com/davidyaha/graphql-redis-subscriptions. Приведено несколько примеров того, как настроить подписки, и они на самом деле работают, но проблема, с которой я сталкиваюсь, заключается в том, как я могу пройти проверку подлинности и разрешить прослушивание подписки только зарегистрированному клиенту. Я использую Apollo-сервер для обслуживания graphql apis следующим образом:

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);

1 Ответ

0 голосов
/ 24 февраля 2020

Аутентифицировано в опции context apollo-server для аутентификации запроса протокола HTTP. Это означает, что он защитит конечную точку /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 , от которого зависит подписка 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

...