翻译 | 《JavaScript
Everywhere
》第7
章 用户帐户和身份验证(`_`)
写在最前面
大家好呀,我是毛小悠,是一位前端开发工程师。正在翻译一本英文技术书籍。
为了提高大家的阅读体验,对语句的结构和内容略有调整。如果发现本文中有存在瑕疵的地方,或者你有任何意见或者建议,可以在评论区留言,或者加我的微信:code\_maomao
,欢迎相互沟通交流学习。
(σ゚∀゚)σ..
:*☆哎哟不错哦
第7章 用户帐户和身份验证
想像一下自己走在黑暗的小巷里,你即将加入一个“超酷秘密俱乐部”(如果你正在阅读此书,则是当之无愧的成员)。当你进入俱乐部的暗门时,接待员会向你打招呼,并递给你一张表格。在表格上,你必须填写你的姓名和密码,只有你和接待员才能知道。填写完表格后,将其交给接待员,接待员将进入俱乐部的后厅。在后台,接待员使用密钥对你的密码进行加密,然后将加密的密码存储在锁定的文件库中。然后,接待员会在通行币上盖章,然后盖下你的唯一会员ID
。回到前厅,接待员递给你通行币,你将通行币塞到口袋里。现在,每次你返回俱乐部时,只需要出示通行币即可进入。这种互动听起来像是一部低价间谍电影中的东西,但它几乎与每次我们注册Web
应用程序时遵循的过程相同。
在本章中,我们将学习如何构建GraphQL
修改,该修改将允许用户创建一个帐户并登录到我们的应用程序中。我们还将学习如何加密用户的密码并向用户返回令牌,当他们与我们的应用程序交互时,他们可以用来验证其身份。
应用程序认证流程
在开始之前,让我们后退一步,确定用户注册帐户并登录到现有帐户时将遵循的流程。如果你还不了解这里介绍的所有概念,请不要担心:我们将逐步解决它们。
首先,让我们回顾一下帐户创建流程:
-
用户将电子邮件地址、用户名和密码输入到用户界面(
UI
),例如GraphQL
Playground
,Web
应用程序或移动应用程序。 -
用户界面会使用用户信息将
GraphQL
请求发送到我们的服务器。 -
服务器对密码进行加密,并将用户信息存储在数据库中。
-
服务器向用户界面返回一个令牌,其中包含用户的
ID
。 -
UI
在指定的时间段内存储此令牌,并将其与每个请求一起发送到服务器以验证用户。
现在让我们看一下用户登录流程:
-
用户在
UI
的字段中输入其电子邮件或用户名和密码。 -
UI
会使用此信息将GraphQL
请求发送到我们的服务器。 -
服务器解密存储在数据库中的密码,并将其与用户输入的密码进行比较。
-
如果密码匹配,则服务器将向用户界面返回一个令牌,其中包含用户的
ID
。 -
UI
在指定的时间段内存储此令牌,并将其与每个请求一起发送到服务器。
如你所见,这些流程与我们的“秘密俱乐部”流程非常相似。在本章中,我们将重点介绍实现这些交互的API
部分。
密码重设流程
你会注意到,我们的应用程序不允许用户更改密码。我们可以允许用户使用修改密码,但是首先通过电子邮件来验证重置请求更加安全。为简便起见,我们不会在本书中实现密码重置功能,但是如果你对创建密码重置流程的示例和资源感兴趣,请访问JavaScript
Everywhere
Spectrum
社区。
加密和令牌
在探索用户身份验证流程时,我提到了加密和令牌。这些听起来像是神话中的黑暗艺术,所以让我们花点时间仔细研究一下每一项。
加密密码
为了有效地加密用户密码,我们应该结合使用哈希和盐析。
哈希
是通过将文本字符串转换为看似随机的字符串来使其混淆的行为。哈希函数是“一种方式”,这意味着一旦对文本进行哈希,就无法将其还原为原始字符串。密码哈希后,密码的纯文本永远不会存储在我们的数据库中。
盐析
是生成随机数据字符串的行为,该数据字符串将与哈希密码一起使用。这样可以确保即使两个用户密码相同,哈希和盐析版本也将是唯一的。
bcrypt
基于河豚密码 ,通常在一系列网络框架中使用。在Node.js
开发中,我们可以使用 bcrypt
模块对密码进行盐析和哈希处理。
在我们的应用程序代码中,我们将需要使用 bcrypt
模块并编写一个函数来处理盐析和哈希。
盐析和散列示例
以下示例仅用于说明目的。 在本章的后面,我们将密码盐析、哈希与bcrypt
集成在一起 。
// require the module
const bcrypt = require('bcrypt');
// the cost of processing the salting data, 10 is the default
const saltRounds = 10;
// function for hashing and salting
const passwordEncrypt = async password => {
return await bcrypt.hash(password, saltRounds)
};
在此示例中,我可以传递密码 PizzaP
@rty99
,生成的盐析为 ‘ 2 a ‘ `2a` ‘2a‘10
‘ H F 2 r s . i Y S v X 1 l 5 F P r X 697 O ‘ 和