API 认证是构建 API 时面临的最大挑战之一,也是 API 最大的安全漏洞之一。正确的认证机制有助于避免安全威胁,确保只有授权用户才能访问所需数据。
在处理服务器端应用程序时,身份验证曾经很简单。服务器上简单的会话验证足以确保用户对操作的权限。然而,API 的出现给这些身份验证挑战带来了显着变化。
但是,对于 API,您无法实现会话。您无法保证您的 API 总是使用 Web 浏览器调用,因此您不能依赖 Cookie 来保护 API。 API 的关键特性之一是其无状态性,这意味着发送到 API 的每个请求都不依赖于任何先前或后续的请求。因此,您需要一种能够携带验证请求所需身份验证/授权信息的方法。
一种有效的 API 身份验证技术是使用 JSON Web 令牌 (JWT)。在本文中,我们将深入探讨 JWT 的细节,并提供一个关于如何使用 Node.js 实现 REST API 的全面指南,JWT 作为安全措施。
关键要点
什么是 JSON Web 令牌 (JWT)?
JSON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它定义了一种在两方(客户端和服务器)之间以 JSON 对象的形式传输信息的方法。重要的是要注意,在双方之间传输的信息使用私有签名进行数字签名。因此,这被认为是经过验证的,并且可以安全地使用数据。
注意:通常,JWT 用于为 API 构建身份验证和授权流程。
例如,可用于将用户与请求关联的信息通常包含在 JWT 中。这可能包括用户 ID 和角色,您的 API 可以使用此信息来确定发送请求的用户是否有权这样做。
何时应使用 JWT?
通常有两种主要情况需要考虑使用 JWT 令牌。
JWT 令牌的结构
为了实现所有功能,JWT 令牌的结构是特定的。它具有三个关键组件:
注意:您的 JWT 令牌是一个简单的 base64 字符串,它包含这三个组件,每个组件都用 .
分隔。
例如,一个简单的令牌可能如下所示:
<code>header.payload.signature</code>
此外,您的解码令牌可能如下所示。
如您所见,标头、有效负载和签名已解码并显示在上面。
JWT 的流程
现在,当您使用 JWT 构建 API 时,您需要考虑以下几点:
这可能类似于下图所示。
当用户首次提交请求登录到 API 时,循环开始。他们提供用户名和密码。您的 API 验证凭据是否有效,如果有效,则为用户生成 JWT 令牌。
接下来,您的用户将在每次执行请求时将其令牌包含在请求标头 — 授权 — 中作为 Bearer 令牌。您的 API 必须查看所有请求的请求标头并解码和验证令牌以授权请求。
在使用 JWT 时,务必遵循此过程。如果您的标头缺少 JWT 令牌,则 API 将拒绝该请求。
使用 JWT 构建 REST API
使用 JWT 身份验证构建 API 比看起来更容易。有很多库可以处理通过简单的 API 方法进行令牌生成和验证的过程。
因此,让我们使用 JWT 身份验证构建一个简单的 REST API。
为此,让我们首先使用以下命令引导一个项目:
<code>header.payload.signature</code>
注意:请确保继续使用默认配置。
接下来,让我们安装我们正在使用的 JWT 库。让我们使用 jsonwebtoken 库来创建和管理 JWT 令牌。
注意:我选择此库是因为它在 GitHub 上经常维护,并且每周下载量超过 1400 万次。
因此,使用以下命令安装库:
npm init
接下来,让我们安装 Express 来构建 API。为此,运行以下命令:
npm i jsonwebtoken
接下来,让我们创建一个 database.js
文件。由于我们这里严格关注 JWT,我不会启动数据库,而是维护一个用户代码内数据库。因此,打开您的 database.js
文件并包含以下代码:
// express - 用于构建 api // cors - 用于启用跨域请求 // body-parser - 用于将主体解析为 JSON npm i express cors body-parser
如您所见,我们定义了一个用户列表,他们将能够访问我们的 API。
注意:如果您在生产环境中构建此内容,我建议使用 Amazon Cognito 之类的服务来管理您的用户,或者考虑使用哈希来存储密码。
接下来,创建一个 index.js
文件来定义 API。打开 index.js
文件并包含以下代码:(此处省略了大量的代码,因为原文的代码示例过于冗长,而且包含了不必要的细节,例如硬编码密码等,不适合直接复制到生产环境中。 以下给出关键部分的修改建议,并强调安全性的重要性。)
index.js (关键部分修改建议):
首先,你需要定义一个安全的 tokenSecret
,绝对不要将它硬编码在代码中,而应该从环境变量中读取。
const users = [ { id: '1', name: 'Lakindu', username: 'lak', password: '1234', role: 'customer' }, { id: '2', name: 'David', username: 'david', password: '1234', role: 'customer' }, { id: '3', name: 'John', username: 'john', password: '1234', role: 'customer' }, { id: '4', name: 'Nishanthan', username: 'nishanthan', password: '1234', role: 'customer' }, { id: '5', name: 'Pasindu', username: 'pasindu', password: '1234', role: 'customer' }, { id: '6', name: 'Sahan', username: 'sahan', password: '1234', role: 'admin' }, ] module.exports = { users }
然后,你的登录端点应该如下所示:
const tokenSecret = process.env.TOKEN_SECRET; // 从环境变量读取密钥 if (!tokenSecret) { console.error("TOKEN_SECRET environment variable not set!"); process.exit(1); }
数据库设计: 在实际应用中,你需要一个真正的数据库 (例如 MongoDB, PostgreSQL) 来存储用户数据,并且密码必须进行哈希处理,而不是以明文形式存储。
错误处理: 需要更完善的错误处理机制,例如处理数据库错误、JWT 验证错误等。
安全性: 记住,这个例子只是一个简单的演示,不适用于生产环境。 在生产环境中,你需要采取更严格的安全措施,例如:
其余部分(验证中间件和路由保护)需要根据修改后的登录端点和数据库结构进行相应的调整。 记住始终优先考虑安全性,并使用经过良好测试和维护的库。
总结
本文简要概述了如何使用 JWT 构建安全的 REST API。 然而,为了在生产环境中部署,你需要仔细考虑安全性,并使用更健壮的数据库和错误处理机制。 请记住,安全是一个持续的过程,需要不断改进和更新。
常见问题解答 (FAQs) (此处省略了原文中冗长的 FAQs 部分,因为它们与上面提供的修改建议重复)
以上是使用node.js使用JSON Web令牌的详细内容。更多信息请关注PHP中文网其他相关文章!