繁体   English   中英

如何使用Express和Apollo-Server获取HTTP授权header

[英]How To Get HTTP Authorization header With Express and Apollo-Server

我无法在我的 Apollo 服务器上访问每个 HTTP 请求中的“授权”header,用 express 实现。 这是我对 express、Apollo-Server、CORS 等的设置。

const corsConfig = {
  credentials: true,
  allowedHeaders: ['Authorization'],
  exposedHeaders: ['Authorization']
};

const app = express()

const server = new ApolloServer({
    schema,
    context: ({ req }) => {
      return {
        req
      };
    }
  });

server.applyMiddleware({
  app,
  path,
  cors: corsConfig
});

http.createServer(app).listen(port, () => logger.info(`Service started on port ${port}`));

在我的解析器中,我引入了上下文,特别是 req object(这是一个示例 graphQL 端点解析器):

const exampleQuery = async (parent, input , { req }) => {
    console.log(req.headers); 
    /*
    The output of this log:
      {
        'content-type': 'application/json',
         accept: '*/*',
        'content-length': '59',
        'user-agent': 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)',
        'accept-encoding': 'gzip,deflate',
         connection: 'close',
         host: 'localhost:3301',
        'Access-Control-Allow-Headers': 'Authorization',
        'Access-Control-Expose-Headers': 'Authorization'
    }

    */
}

我已向此端点发送请求,其中包含一个令牌作为值的“授权”header。 但是,授权 header 不在 req.headers object 中(实际上,它也不在整个请求 object 中)。 我确信我的 Postman/Insomnia HTTP 请求到这个端点正在发送授权 header,但是它似乎没有通过我的 Apollo-Server。 任何人都知道为什么授权 header 没有通过?

解决方案:

问题实际上是我使用的是 Apollo 联合微服务架构,它需要在网关上进行额外配置才能将授权 header 传递到解析器所在的各个微服务。 您必须在 ApolloGateway 构造函数中添加 buildService function,您在其中指定 RemoteGraphQLDataSource willSendRequest of context.req.headers.authentication 到底层微服务

它按预期工作,例如

server.ts

import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server-express';
import express from 'express';
import http from 'http';

const corsConfig = {
  credentials: true,
  allowedHeaders: ['Authorization'],
  exposedHeaders: ['Authorization'],
};

const typeDefs = gql`
  type Query {
    hello: String
  }
`;
const resolvers = {
  Query: {
    hello: (_, __, { req }) => {
      console.log(req.headers);
      return 'world';
    },
  },
};
const schema = makeExecutableSchema({ typeDefs, resolvers });

const app = express();
const path = '/graphql';
const port = 3000;
const server = new ApolloServer({
  schema,
  context: ({ req }) => {
    return {
      req,
    };
  },
});
server.applyMiddleware({ app, path, cors: corsConfig });

http.createServer(app).listen(port, () => console.info(`Service started on port ${port}`));

通过curl发送GraphQL查询HTTP请求:

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer abc123" --data '{ "query": "{ hello }" }' http://localhost:3000/graphql
{"data":{"hello":"world"}}

服务器端日志:

Service started on port 3000
{ host: 'localhost:3000',
  'user-agent': 'curl/7.54.0',
  accept: '*/*',
  'content-type': 'application/json',
  authorization: 'Bearer abc123',
  'content-length': '24' }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM