ApolloServer: передача заголовков от запроса до бэкэнда - PullRequest
0 голосов
/ 28 марта 2020

У меня есть ApolloServer, который я использую для сшивания нескольких внутренних процессов - он буквально ничего не делает, кроме как представляет для них единый фронт - и я хочу, чтобы заголовки, передаваемые в запросе (которые приходят из проектов React), проходили unmolested к backends (Clojure и Rails).

У меня есть этот код:

    let link = new HttpLink({
        uri,
        headers: {"x-api-token": key},
        fetch
    })

И, возможно, неудивительно, единственное, что видит серверная часть, это "x-api- лексема».

Я обнаружил, что могу извлечь заголовки из контекста:

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
  context: (ctx) => ({
    headers: ctx.req.headers
  }),
  extensions: [() => new BasicLogging()]
});

И я пытаюсь как-то запихнуть их в исходящие заголовки, но кажется, что далеко амбар. (И я еще не понял этого, поэтому я не уверен, что я на правильном пути.) Нет ли способа сказать ApolloServer, что он просто пропускает запросы? посторонний комментарий в скобках. Добавлен код.

Вот иллюстрация проблемы, созданной с помощью онлайн-примеров:

const { ApolloServer, gql } = require('apollo-server');
var fetch = require('node-fetch')
var {introspectSchema, makeRemoteExecutableSchema} = require('graphql-tools')
var {HttpLink} = require('apollo-link-http')

const genSchema = async () => {
  http = new HttpLink({
    uri: "http://localhost:3000/graphql",
    headers: {"x-api-token": "Whatever"},
    fetch
  })
  const link = setContext((request, previousContext) => ({
    headers: {
      'Authentication': "1234xyz"
    }
  })).concat(http);
  const schema = await introspectSchema(link)
  return makeRemoteExecutableSchema({schema, link})
}

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
});

exports.startServer = async () => {
  const apolloServer = (await server()).listen({port: process.env.PORT || 4000});
  apolloServer.then(({url}) => console.log(`Server ready at ${url}`));
  return apolloServer
}

Поместите это на сервер. js и следующее в индекс. js, и вы можете запустите с "индекс узла. js" (при условии, что у вас есть служба graphql на locahost: 3000):

var server = require('./server')
server.startServer()

То, что вы увидите, это то, что "x-api-token" проходит, но " Аутентификация »не имеет. В примере кода используется:

'Authentication': `Bearer ${previousContext.graphqlContext.authKey}`,

... который я, вероятно, мог бы использовать для извлечения заголовков, но буквально ничего, что я вставил, не доходило до серверной стороны.

1 Ответ

0 голосов
/ 29 марта 2020

ОК, я нашел эту статью:

https://medium.com/wehkamp-techblog/using-headers-with-apollo-datasources-1c4c019d080c

Хитрость заключается в том, чтобы установить контекст при создании сервера, который я рассчитывал, но вы не может просто "пройти" по ключу заголовков. Итак, создание сервера может выглядеть так:

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
  context: ({ req }) => ({
    req,
    customHeaders: {
      headers: {
        ...req.headers,
      },
    },
  }),
});

Вы должны вставить их в исходящее сообщение. Вы, несомненно, могли бы отправить их всех, но так как теперь я обеспокоен тем, что я мог бы перезаписать, я просто вытащил один:

const http = new HttpLink({
  uri: "http://localhost:3000/graphql",
  fetch
})

const link = setContext((request, previousContext) => ({
  headers: {
    'NewHeader': (previousContext.graphqlContext && previousContext.graphqlContext.customHeaders.headers["myheader"]),
  }
})).concat(http);

Содержимое входящего заголовка "myheader" будет выходить по адресу бэкэнд как "NewHeader".

...