2. 认证:识别用户
5m

概述

在上节中,我们了解到 认证是确定给定用户是否已登录,然后确定某人是谁的过程。换句话说,认证是检查用户所言是否属实。

Airlock 使用简化的登录流程:用户可以以主机帐户或访客帐户登录。你可以在以下位置测试登录流程https://127.0.0.1:3000/login(或 已部署的 Airlock 演示应用)。

在本课程中,我们将

  • 学习如何使用 context 对象使用 HTTP 标头认证用户。

🕵️‍♂️ 认证

有许多方法可以提供认证凭据,例如 HTTP 标头、会话 cookie 或 JSON web 令牌。

Airlock 使用 HTTP 标头。让我们仔细看看它是如何工作的。

在客户端

记住 以 HTTP 请求的形式从客户端发送到服务器。在 Airlock 中,每个操作都包含一个 HTTP Authorization 标头,其中带有 Bearer 令牌,以提供身份验证凭据。该标头类似于以下内容:

Authorization: Bearer user-1

注意:如果您好奇,您可以在 client/src/index.jsauthLink 设置的地方)中看到添加此标头的客户端代码。


设置客户端身份验证不在本任务的范围内,因此我们不会详细介绍这一点。有关更多信息,您可以查看 Apollo Client 身份验证文档

在上面的示例中,user-1 令牌指示哪个用户正在提出请求。我们可以看到,令牌只是“user-1”,这是用户的确切 ID。在生产环境中,此令牌通常采用临时编码字符串的形式,该字符串由您的用户管理系统(如 Auth0 或 Okta)生成。但出于本课程的目的,我们坚持使用普通用户 ID,以便在测试时简化操作。

在服务器端

接收到传入的客户端 时,它会从请求标头中检索令牌,并尝试对用户进行身份验证。让我们来看看 Airlock 如何细分此过程中的步骤:

  1. 从客户端请求的 Authorization 标头中检索 Bearer 令牌。
  2. 如果存在 Bearer 令牌,服务器会将其传递给 accounts 服务,该服务尝试登录相应用户。
  3. 如果用户登录成功,accounts 服务将会返回用户个人资料数据对象。然后,将用户的 ID 和角色添加到context 对象中以供每个使用。

从那里开始,每个都能出于授权目的使用这些用户属性,以确定用户拥有哪些数据访问权限。(不过我们会在下一课中介绍!)

相关代码位于server/index.js 文件中,ApolloServer 初始化的context 属性中:

server/index.js
// ...
context: async ({ req }) => {
// 1) Retrieve the Bearer token from the request's Authorization header
// (Note the lowercase "a" in authorization,
// because all headers are transformed to lowercase)
const token = req.headers.authorization || '';
// Get the user token after "Bearer "
const userId = token.split(' ')[1]; // e.g. "user-1"
// Initialize the userInfo object where the user's id and role will be stored
// with a successful authentication
let userInfo = {};
if (userId) {
// 2) Authenticate the user using the accounts API endpoint
const { data } = await axios.get(`https://127.0.0.1:4011/login/${userId}`).catch((error) => {
throw AuthenticationError();
});
// 3) After a successful login, store the user's id and role
// in the userInfo object,
// which will be passed to `context` below for the resolvers to use
userInfo = { userId: data.id, userRole: data.role };
}
// for RESTDataSource classes
const { cache } = server;
// Below is the `context` object resolvers will have access to
return {
...userInfo,
dataSources: {
bookingsDb: new BookingsDataSource(),
reviewsDb: new ReviewsDataSource(),
listingsAPI: new ListingsAPI({cache}),
accountsAPI: new AccountsAPI({cache}),
paymentsAPI: new PaymentsAPI({cache}),
},
};
},
// ...

练习

以下哪项描述了 Airlock 应用如何对用户进行身份验证?

要点

  • 一种用户身份验证的方式是通过传递 HTTP Authorization 请求标头,其中包含 它发送到服务器的操作。
  • 身份验证逻辑可以在context 属性中编写ApolloServer 构造函数,以便用户信息对每个可用。

下一步

既然我们已经了解了 Airlock 如何处理认证,下一步是授权。在下一课中,我们将了解 Airlock 如何使用 context 对象中的用户信息来确定用户是否有权执行某些 .

上一步