4. 超级图中的身份验证
5m

概览

要继续我们的迁移计划,我们需设置以在原始服务器端口(端口 4000)上运行。在我们对此进行编码之前,我们先了解下我们如何确保 和整体 能够正确处理身份验证和授权。在本课中,我们将:

  • 回顾 Auth 如何在 Airlock 的整体架构中运作
  • 了解如何将授权标头从 传播到其

Airlock 中的 Auth 如何运作

Airlock 有两种类型的用户:房东房客。每位用户都可以执行不同种类的操作。

在以房东身份登录时,您可以:

  • 创建房源
  • 管理房源预订
  • 撰写房客评论

在以房客身份登录时,您可以:

  • 预订住宿地点
  • 撰写位置和房东评论
  • 管理您的空间积分

目前,房客用户无法创建房源,而房东用户无法预订住宿地点。

通过这些业务规则,我们的 Airlock API 需要控制哪些用户能够看到和交互图形中的特定。这就是身份验证和授权发挥作用的地方。

  • 身份验证就是确定给定用户是否已登录,随后确定他是谁。(用户是他们声称的自己。)
  • 授权就是确定给定用户有权限做什么或看到什么。(允许用户执行他们试图执行的操作。)

注意:这是您第一次使用身份验证?请查看身份验证和授权旁支任务以详细了解如何在单个中验证用户登录和权限。

在 Airlock 中,我们使用 HTTP 标头,特别是带有 Bearer 令牌的Authorization标头来提供我们的用户证书。标头类似于这样:

Authorization: Bearer user-1

收到传入客户端后,它从请求头中检索令牌并尝试使用帐户服务对用户进行身份验证。身份验证成功后,帐户服务将返回包含userIduserRole的”对象,然后 会将对象添加到contextValue对象中,对每个 都可用。

Airlock 使用字段级授权。这意味着每个都会检查已登录用户是否有权访问的该部分。他们使用userIduserRolecontextValue对象中获取属性。

超级图中的身份验证

在最初的单一架构中,从客户端接收授权头,做一些逻辑来提取所需的用户信息,然后通过contextValue对象将其信息传递给其

架构中,故事仍然类似。路由器将从客户端接收授权标头,然后将此信息传递给其子图。每个将执行相同的逻辑,以提取用户信息并将其传递给其

注意:在中实现身份验证还有其他方法,例如在架构中使用授权,使用协处理器或使用 JWT 身份验证插件。在此课程中,我们将重点介绍中使用标题传播进行身份验证。您可以结合这些策略来处理多个身份验证要求并实践“纵深防御”。有关这些方法的更多信息,查看此 Apollo 技术笔记

如何将此信息传递给其需要做什么才能将此信息传递给 ?让我们深入了解这些问题,并在“中的身份验证”这个故事中回答它们!

对用户进行身份验证

故事的开头与我们的 之旅相同:即客户端向服务器发出请求。此特定请求包括一个Authorization标头,其中包含已登录用户的凭证。

HTTP request with auth header is sent from the browser to the router

在收到该请求后,开始创建,使用作为参考,以确定要为特定查询哪个

The router builds a query plan to resolve the request

下一步,执行。从顶部开始,向发送请求。该请求包含客户端发送的Authorization标头!

但是如何知道要传递该标头?这在配置中都有说明!

向子图发送 HTTP 标头

我们启动时,可以选择使用--config标志传入配置文件。这样,我们可以通过多种方法自定义,例如配置 CORS(我们在最终第 1 部分看到了它),和 HTTP 标头。

使用配置文件时,我们会告诉Authorization标头在其的每个请求中发送给。我们将在下一课中了解此配置的实际作用。

The config file provides instructions for which headers to send to the subgraphs

发送到子图中

接收到来自 的请求时,它从请求中访问 Authorization 标头并尝试对用户进行身份验证。

如果尝试不成功,则 停止并发送 AuthenticationError 返回到 ,后者会将它直接发送回客户端。

The subgraph attempts to authenticate the user, returning an Authentication Error to the router if unsuccessful

如果身份验证成功,则 将包含用户信息的对象放在一起,并使其在上下文中可用。此用户信息对象可以以最有利于子图的 的方式构建,并通过 contextValue 对象传递。

解析 的方式与任何其他 相同:它们使用自己的 来检索和填充请求的数据。它们可以在 contextValue 对象中使用用户信息,以检查对特定业务规则的保护以及谁有权访问它!

The subgraph resolves the operation using its resolver functions and data sources

返回路由器

发送回请求的数据,而路由器继续执行其 ,最终将所有这些响应合并到单个 JSON 对象中。

最后, 将最终 JSON 对象发送回客户端。这就是我们的 之旅的终点!

A doodle detailing the journey of authentication in a supergraph in its entirety

练习

以下哪些选项可以作为路由器 config 文件的一部分?

要点

  • 在 Airlock 中,客户端将其请求发送到 ,同时添加了一个名为 Authorization的 HTTP 标头,其中包含当前用户的身份验证令牌。
  • 可以用一个配置文件进行自定义,以将 HTTP 标头传递给其
  • 将用户的身份验证令牌传递给 ,该 检查令牌是否有效用于登录。
    • 如果登录不成功,将抛出AuthenticationError并将其发回
    • 如果登录成功,将当前用户信息添加到其contextValue对象中,其可通过此对象访问,以实现级授权。

下一步

我们已经了解如何在中处理身份验证,因此让我们整合所有内容并在代码中实现这一点!

上一步

分享您对本课的疑问和评论

您的反馈有助于我们提升!如果您遇到了困难或困惑,请告知我们,我们会为您提供帮助。所有评论都是公开的,且必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被删除。

您需要一个 GitHub 帐户才能在下面发帖。没有帐户? 转而发帖至我们的 Odyssey 论坛。