You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:25:28