Подписка на GraphQL, websocket, nodejs, экспресс-сессия - PullRequest
0 голосов
/ 11 сентября 2018

Я использую Apollo Server 2 (, но эта проблема не только с Apollo ) и Express.js vanilla (с apollo-server-express).

Все хорошо работает и с Подписками , кроме механизма Экспресс-сессия .

Проблема:

Я использую cookie-сессия (https://github.com/expressjs/cookie-session,, но я думаю, что это то же самое для express-session middleware) и когда мой браузер устанавливает новое соединение на моем сервере хук ApolloServer onConnect не имеет атрибута req, а также req.session и так далее ...

Что я могу сделать, так это разобрать куки с webSocket.upgradeReq.headers.cookie в onConnect хуке жизненного цикла, но мне кажется, что он очень хакерский.

Код:

const { ApolloServer } = require('apollo-server-express')

const typeDefs = require('../src/graphql/types')
const resolvers = require('../src/graphql/resolvers')
const models = require('../src/models')

const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req, connection }) => {
    // connection exists only on webSocket connection
    if (connection) {
      return {
        currentUser: connection.context.currentUser // <-- I NEED THIS!
      }
    }
    // if not a (webSocket) connection it is a "default" HTTP call
    return {
      models,
      currentUser: { id: req.user.id }
    }
  },
  subscriptions: {
    onConnect: (connectionParams, webSocket) => {
      // "connectionParams" is from the client but I cannot use it because cookies are HTTP-Only
      // I can retrieve cookies from here: "webSocket.upgradeReq.headers.cookie" but then I need to parse them which seems a bit hacky to me
      // return { currentUser: req.user.id } // <-- I NEED THIS (req.user.id doesn't exists)!
    }
  }
})

module.exports = apolloServer

Я не могу найти ничего на сайте Apollo Server Docs (для других тем очень хорошо задокументировано!).

Где я не так делаю?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

https://www.apollographql.com/docs/apollo-server/features/subscriptions.html#Authentication-Over-WebSocket

Похоже, что вы можете передать необходимые данные cookie на стороне клиента для получения в контексте на сервере.

Передать параметры для подключения через веб-сокет:https://www.apollographql.com/docs/react/advanced/subscriptions.html#authentication

0 голосов
/ 08 января 2019

См. Этот комментарий: https://github.com/expressjs/cookie-session/issues/117#issuecomment-452046225 от dougwilson для получения значений сеанса.

Если вы просто хотите получить содержимое сеанса (а не записывать новый сеанс - что было бы невозможно без разрешения в любом случае), вы, вероятно, могли бы просто использовать модуль cookie напрямую, что и используется в этом модуле. капюшон, чтобы прочитать печенье и проверить подпись. Возможный пример:

const Cookies = require('cookies')

// …

const cookies = new Cookies(req, null, { keys }) const session =
JSON.parse(Buffer.from(cookies.get('session'),'base64').toString('utf8'))

И onConnect вернуть все, что вам нужно использовать для подписки ()

...