Javascript ApolloServer 2.0上下文和GraphQL API的公共/私有部分

Javascript ApolloServer 2.0上下文和GraphQL API的公共/私有部分,javascript,express,graphql,apollo-server,Javascript,Express,Graphql,Apollo Server,我不是一个专业人士,但我已经开始和ApolloServer/Express后端托管一个网站,在那里我将为会员提供公共部分和私人部分。我在登录中生成JWT令牌,并将其发送到客户端 在上下文中,我想检查是否设置了令牌,以及基于这个句柄允许哪些GraphQL查询。我的Express/Apollo服务器目前看起来像这样 const server = new ApolloServer({ typeDefs, resolvers, context: async ({ req }) => {

我不是一个专业人士,但我已经开始和ApolloServer/Express后端托管一个网站,在那里我将为会员提供公共部分和私人部分。我在登录中生成JWT令牌,并将其发送到客户端

在上下文中,我想检查是否设置了令牌,以及基于这个句柄允许哪些GraphQL查询。我的Express/Apollo服务器目前看起来像这样

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: async ({ req }) => {
    // get the user token from the headers
    const token = (await req.headers.authorization) || '';

    if (token) {
      member = await getMember(token);
    }
  }
});
问题是,这会从任何查询中锁定GraphQLAPI,例如,我希望/需要访问注册/登录


有谁能解释一下这一点来帮助我理解我需要做些什么来让它工作。

我这样做的方式是,我甚至会在graphql服务器之前构建auth中间件,因为有时需要在其他中间件中获得关于已验证用户的信息,而不仅仅是graphql模式。将添加一些代码,您需要完成它

const auth = (req, res, next) => {
  if (typeof req.headers.authorization !== 'string') {
    return next();
  }

  const header = req.headers.authorization;
  const token = header.replace('Bearer ', '');
  try {
    const jwtData = jwt.verify(token, JWT_SECRET);
    if (jwtData && jwtData.user) {
      req.user = jwtData.user;
    } else {
      console.log('Token was not authorized');
    }
  } catch (err) {
    console.log('Invalid token');
  }
  return next();
};
这样,如果设置了正确的令牌,我将用户注入到每个请求中。然后在apollo服务器2中,您可以按如下方式进行操作

const initGraphQLserver = () => {
  const graphQLConfig = {
    context: ({ req, res }) => ({
      user: req.user,
    }),
    rootValue: {},
    schema,
  };

  const apolloServer = new ApolloServer(graphQLConfig);
  return apolloServer;
};
此函数将启动Apollo服务器,您将在正确的位置应用此中间件。在应用apollo服务器2之前,我们需要有身份验证中间件

app.use(auth);

initGraphQLserver().applyMiddleware({ app });
假设应用程序是

const app = express();
现在,您将把user from user jwtData作为“user”注入到每个解析器的上下文中,或者在其他中间件的req.user中,您可以像这样使用它。这是一个用于说明哪个用户是否经过身份验证的查询

  me: {
    type: User,
    resolve: async (source, args, ctx) => {
      const id = get(ctx, 'user.id');

      if (!id) return null;

      const oneUser = await getOneUser({}, { id, isActive: true });
      return oneUser;
    },
  },
我希望即使使用细分代码,一切都有意义。请随时提问。当然还有更复杂的身份验证,但对于简单的应用程序来说,这个基本示例通常就足够了


最好的大卫

谢谢你抽出时间。我只是看了一下代码,因为我现在正在工作,但今晚会坐下来试试:)我想我理解了大部分:)会带着结果回来的。我试了一下,但是在Apollo服务器的上下文中我不需要很多东西吗?不确定上下文的每个参数都来自何处。我确实了解express的auth中间件,它需要在应用中间件之前执行。嗨,伙计,很抱歉造成混淆,我是从我的项目中复制的,因此还有很多额外的东西。我已经删除了它,所以希望它现在更清晰。请注意,在我的项目中,我使用了graphql js库中基于类的方法定义的模式,而不是graphql工具,因为您有typeDefs、解析器等,而不是apollo服务器构造函数中的模式。感谢您提供的信息。我想我现在明白了:)