认证

在本章节内容中,我们将学习如何使用 Apollo 和 Graphcool 实现用户认证功能。

准备 React 组件

我们将从编写 Login 组件开始。

让我们快速了解这个新组件的结构,它有两个主要的状态。

第一个状态是为已经存在的用户来登录使用的。在这种情况下组件只渲染两个 input 让用户输入 emailpassword。这时 state.login 的值是 true

另外一种状态是为了用户注册使用的。组件需要渲染三个 input 让用户输入 emailpasswordname。这时 state.login 的值是 false

接下来,我们还需要提供 constants.js 文件,用于为浏览器的 localStorage 中存储的凭据的键。

然后我们需要添加一个新的路由。

最后,继续添加 LinkHeader,让用户可以浏览到 Login 页面。

首先从本地存储中检索 userId。如果 userId 不可用,则 提交按钮 将不再被渲染。这样,您确保只有经过身份验证的用户才能创建新的链接。

还在 Header 组件中右侧添加了第二个按钮,用户可以使用它来登录和注销。

下面是 Login 组件渲染后的页面:

Login.js 中实现身份验证功能之前,需要准备 Graphcool 项目并在服务器端启用身份验证。

启用邮件-密码认证以及更新模式

这条命令将打开一个网页,我们将通过这个页面来配置我们的 Graphcool 项目。

这将打开弹出窗口,允许我们启用 Graphcool 基于电子邮件的身份验证机制。

通过开启 邮件-密码 认证机制我们可以在项目中添加两个变更。

# 1. 创建用户
createUser(authProvider: { email: { email, password } }): User

# 2. 登录
signinUser(email: { email, password }): SignInUserPayload

# SignInUserPayload bundles information about the `user` and `token`
type SignInUserPayload {
  user: User
  token: String
}

接下来,必须确保身份验证提供程序引入的更改反映在本地项目文件中。可以使用 graphcool pull 来更新本地模式文件。

注意:在获取远程模式之前,系统将要求确认要覆盖当前的项目文件。可以输入 y 来确认。

这将使模式 version 变为 2 并更新 User 类型,现在还包括 emailpassword 字段:

type User implements Node {
  createdAt: DateTime!
  email: String @isUnique
  id: ID! @isUnique
  password: String
  updatedAt: DateTime!
}

接下来,需要对模式进行一次修改。通常,两种更新 Graphcool 项目的模式的方法:

  1. 使用基于 Web 的 Graphcool Console 来直接更改模式。
  2. 使用本地的 Graphcool 项目文件和 CLI。

我们在模式中添加了两个东西:

  • User 类型中添加了一个新的字段 name
  • User 类型和 Link 类型中申明了关联。 用户有许多链接而链接是由用户创建的。

这是终端输出结果:

$ graphcool push
 ✔ Your schema was successfully updated. Here are the changes: 

  | (*)  The type `User` is updated.
  ├── (+)  A new field with the name `name` and type `String!` is created.
  |
  | (+)  The relation `UsersLinks` is created. It connects the type `Link` with the type `User`.

Your project file project.graphcool was updated. Reload it in your editor if needed.

注意: 在使用 graphcool push 命令将本地的模式更新推送到 graphcool 后,我们也可以使用 graphcool status 命令来查看当前模式的状态。

完美,我们已经在应用程序中实现身份验证功能。

实现登录变更

createUsersigninUser 是两个常规的 GraphQL 变更,我们可以使用与以前使用的 createLink 变更相同的方式。

请注意,这次我们使用 compose 作为导出语句,因为我们想要包含多个变量。

在我们仔细观察这两个变更之前,请继续添加所需的导入。

现在,让我们来看一下刚才添加到组件中的两个变更的作用。

SIGNIN_USER_MUTATION 变更跟之前的变更很相似。它接收 emailpassword 作为参数返回有关 user 的信息以及后续请求用来验证用户的 token

CREATE_USER_MUTATION 有点不一样! 在这里,我们实际定义了两个变更!执行顺序总是 从上到下。也就是说 createUser 变更将先执行而后在执行 signinUser 变更。通过创建两个变更使得在一个请求中注册和登录!

好的,剩下的一切就是调用代码中的两个变更!

代码很简单。如果用户只想登录,会调用 signinUserMutation,并将提供的 emailpassword 作为参数传递。否则使用 createUserMutation,也可以传递用户的 name。执行变更后,将 idtoken 存储在 localStorage 中,并返回到根路径。

现在可以通过提供一个 名称电子邮件密码 来创建一个帐户。一旦这样做,提交 按钮将再次出现:

更新 createLink 变更

既然现在可以验证用户,并且在 LinkUser 类型之间添加了新的关系,还可以确保在应用程序中创建的每个新链接都可以存储有关发布用户的信息。这就是 Link 上的 postBy 字段的作用。

有两个主要的变化。首先在变更中添加了另一个参数,该变量表示发布链接的用户的 id。其次,还将 postedBy 信息包含在 有效载荷 中。

现在需要确保在 _createLink 中调用变量时包含发布用户的 id

还需要导入 GC_USER_ID

完美!在发送变更之前,我们将从 localStorage 中检索相应的用户标识。如果成功,将传递给 createLinkMutation 的调用,以便每个新的 Link 从现在开始存储有关创建它的 User 的信息。

如果以前没有这样做,请继续测试登录功能。运行 yarn start 并打开http//localhost3000/login。然后单击 注册 按钮,并为要创建的用户提供一些用户数据。最后点击 创建帐户 按钮。如果一切顺利,应用程序将返回到根路径,并创建用户。您可以通过检查 数据浏览器 或在 playground 中发送 allUsers 查询来验证新用户是否存在。

配置 Apollo 的认证令牌

现在,用户可以登录并获取一个令牌,它可以根据 Graphcool 后端进行身份验证,实际上需要确保令牌被附加到发送到 API 的所有请求。

由于所有 API 请求实际上都是由应用程序中的 ApolloClient 创建和发送的,所以需要确保它知道用户的令牌。幸运的是,Apollo 提供了一种通过使用中间件 验证所有请求的好方法。

就是这样 - 如果 token 可用,那现在所有的 API 请求都将被认证。

注意:在实际应用程序中,需要配置项目的 授权规则 以确定哪种操作需要通过身份验证并且应该允许未认证的用户执行。

Unlock the next chapter
在启用邮件加密码认证后,Graphcool 项目中添加的两个变更的名称是什么?
用户登录和用户注销
用户注册和创建用户
创建用户和用户登录
用户注册和用户注销