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

Posted

技术标签:

【中文标题】如何使用 GraphQL 构建经过身份验证的查询?【英文标题】:How do I structure authenticated queries with GraphQL? 【发布时间】:2016-04-29 09:54:07 【问题描述】:

我正在考虑编写一个执行以下操作的 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
  

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

【问题讨论】:

【参考方案1】:

我提供了一种方法,将解析器构建为较小函数的组合,以帮助解决这个确切的问题。您可以在此处查看完整答案:How to check permissions and other conditions in GraphQL query?。

基本概念是,如果您将解析器构建为组合在一起的小函数,您可以将不同的授权/身份验证机制叠加在一起,并在第一个不满足的情况下抛出错误。这将有助于保持您的代码干净、可测试和可重用:)

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

黑客愉快!

【讨论】:

【参考方案2】:

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

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...

【讨论】:

以上是关于如何使用 GraphQL 构建经过身份验证的查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphql 和护照设置身份验证但仍使用 Playground

如何从 Nuxt 前端访问经过身份验证的 GraphQL API

如何使用 Firebase Auth 作为 OIDC 向 Amplify GraphQL 发出经过身份验证的请求?

如何在 Graphql 中删除自省查询的身份验证

未处理的拒绝(错误):GraphQL 错误:未经过身份验证

JWT 身份验证:使用 UI 令牌对 Graphene/Django (GraphQL) 查询进行身份验证?