如何使用 GraphQL 构建经过身份验证的查询?

How do I structure authenticated queries with GraphQL?

我正在考虑编写一个 API 来执行以下操作:

我会像这样构建查询:

// return the name and id of all the user's maps
maps(authToken="…") {
  name,
  id
}

// return all the items of a single map
maps(authToken="…") {
  map(name=“Quotes") {
    items
  }
}

// OR by using the map_id
maps(authToken="…") {
  map(id=“…") {
    items
  }
}

所以,我的问题是,这是正确的还是我需要以不同的方式构建它?

我建议在 GraphQL 本身之外构建身份验证,并让您的模式逻辑处理授权。例如,如果您使用 express-graphql NPM 模块,您可以检查您的 cookie 或 HTTP Basic Auth 或您想要使用的任何机制来获取您的身份验证令牌,然后通过架构向下传递您经过身份验证的查看器对象rootValue,在查询解析期间的每个级别都可用:

app.use('/graphql', (request, response, next) => {
  const viewer = getViewerFromRequest(); // You provide this.
  const options = {
    rootValue: {
      viewer,
    },
    schema,
  };

  return graphqlHTTP(request => options)(request, response, next);
});

然后在模式中您可以访问您的 rootValue 并可以将其用于访问控制和授权目的:

resolve: (parent, args, {rootValue}) => {
  const viewer = {rootValue};

  // Code that uses viewer here...
}

请注意,从 graphql v0.5.0 开始,the resolve signature has changed 和第三个 "context" 参数已插入参数列表中的位置 3。此参数适用于向下传递身份验证令牌或类似令牌:

resolve: (parent, args, authToken, {rootValue}) => {
  // Code that uses the auth token here...
}

我提供了一种将解析器构造为较小函数的组合的方法,以帮助解决这个确切的问题。您可以在此处查看完整答案:.

基本概念是,如果将解析器构造为组合在一起的小函数,则可以将不同的 authorization/authenication 机制层层叠加,并在第一个不满足的机制中抛出错误。这将有助于保持您的代码干净、可测试和可重用:)

是的,解析器上下文是存储身份验证信息以及可能需要在整个解析器中使用的其他好东西的好地方。

祝您黑客愉快!