如何在Apollo Server 2.0 Beta中读取Auth Header?能否沿用1.x的中间件方案?
嘿,刚好对Apollo Server 2.0 Beta的认证处理比较熟,来给你详细解答下:
一、在Apollo Server 2.0 Beta中读取Auth Header的方法
在2.0 Beta里,读取Auth Header最直接的方式是通过context函数来获取请求头信息,具体分两种场景:
1. 纯Apollo Server(不依赖Express)
Apollo Server 2.0的context配置支持传入一个函数,这个函数会接收请求对象(HTTP环境下是req),你可以直接从req.headers里取出Authorization头:
const { ApolloServer, gql } = require('apollo-server'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: (_, __, context) => { // 从context中获取提前处理好的auth header const authHeader = context.authHeader; return authHeader ? `Hello, authenticated with ${authHeader}` : "Hello, guest"; }, }, }; const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { // 取出Authorization头,默认空字符串避免报错 const authHeader = req.headers.authorization || ''; // 这里还可以做token解码、验证逻辑,比如解析JWT // const user = verifyToken(authHeader.split(' ')[1]); return { authHeader /*, user */ }; }, }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
2. 集成Express的场景(apollo-server-express)
如果你是和Express一起搭建服务,同样可以用上面的context函数方式,或者结合Express的中间件来处理(下面会详细说)。
二、Apollo Server 1.x的Express中间件修改Context方式在2.0 Beta中是否可行?
答案是完全可行,只是context的定义方式有小变化,核心逻辑可以复用:
在1.x里,你可能会写一个Express中间件,把认证信息挂载到req对象上,然后在context里直接使用。2.0 Beta依然支持这种模式,只需要在Apollo Server的context函数里,把req上的认证信息传递给解析器即可。
举个完整的例子:
const express = require('express'); const { ApolloServer, gql } = require('apollo-server-express'); const app = express(); // 自定义Express认证中间件 app.use((req, res, next) => { const authHeader = req.headers.authorization || ''; // 这里可以做你的认证逻辑,比如验证JWT if (authHeader.startsWith('Bearer ')) { const token = authHeader.split(' ')[1]; // 假设verifyToken是你的验证函数,返回用户信息 // const user = verifyToken(token); req.user = { id: '123', username: 'Chris' }; } else { req.user = null; } next(); }); const typeDefs = gql` type Query { currentUser: String } `; const resolvers = { Query: { currentUser: (_, __, context) => { return context.user ? `Current user: ${context.user.username}` : "No user logged in"; }, }, }; const server = new ApolloServer({ typeDefs, resolvers, // 把Express中间件处理好的user传到context context: ({ req }) => { return { user: req.user }; }, }); // 将Apollo Server挂载到Express应用 server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`) );
简单来说,2.0 Beta并没有抛弃Express中间件的使用方式,只是把context从对象改成了函数,让你更灵活地从请求对象中提取需要的信息。你完全可以继续沿用1.x里用Express中间件预处理认证的思路,只需要在context函数里把中间件处理好的数据传递给解析器就行。
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

