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

时间:2016-01-22 17:37:35

标签: api authentication graphql

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

  • 为用户提供身份验证令牌的注册和登录用户
  • 创建地图(数据示例:{ name: “Quotes”, attributes: [“quote”, “author"] }
  • 创建地图项(数据示例:{ quote: "...", author: "..." }

我会像这样构建查询:

// 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
  }
}

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

2 个答案:

答案 0 :(得分:24)

我建议在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...
}

答案 1 :(得分:1)

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

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

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

快乐黑客!