如何使用 Express 和 Apollo-Server 获取 HTTP 授权标头
Posted
技术标签:
【中文标题】如何使用 Express 和 Apollo-Server 获取 HTTP 授权标头【英文标题】:How To Get HTTP Authorization header With Express and Apollo-Server 【发布时间】:2020-08-19 10:38:21 【问题描述】:我无法访问我的 Apollo-Server 上每个 HTTP 请求中的“授权”标头,使用 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 对象(这是一个示例 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'
*/
我已经向这个端点发送了请求,带有一个“授权”标头,其中包含一个令牌作为值。但是,Authorization 标头不在 req.headers 对象中(实际上,它也不在整个 req 对象中)。我确信我对这个端点的 Postman/Insomnia HTTP 请求正在发送 Authorization 标头,但是它似乎没有通过我的 Apollo-Server。 任何人都知道为什么 Authorization 标头没有通过?
解决方案:
问题实际上是我使用的是 Apollo 联合微服务架构,它需要在网关上进行额外配置才能将 Authorization 标头传递到解析器所在的各个微服务。您必须在 ApolloGateway 构造函数中添加 buildService 函数,在其中指定一个 RemoteGraphQLDataSource willSendRequest of context.req.headers.authentication 到底层微服务
【问题讨论】:
在您的前端 javascript 代码中,您如何设置凭据模式?例如,对于 XHR,您需要设置 'xhr.withCredentials = true' developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…。使用 Fetch API,您需要设置 "credentials: 'include'" developer.mozilla.org/en-US/docs/Web/API/Fetch_API/…. @sideshowbarker 现在我不涉及任何前端代码。我只是向带有 Postman/Insomnia 的“exampleQuery”端点发送一个带有“授权”标头的 graphQL 发布请求。我的目标是在 exampleQuery 内的 req.headers["Authorization"] 中访问该标头。 【参考方案1】:它按预期工作,例如
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'
【讨论】:
以上是关于如何使用 Express 和 Apollo-Server 获取 HTTP 授权标头的主要内容,如果未能解决你的问题,请参考以下文章
使用 Node.js 和 Express 发布时如何访问请求正文?