身份认证和授权是任何 Web 应用程序的关键组成部分。在过去,服务器端使用 Cookie 和 Session 进行身份认证和授权。但是,由于 Stateful 机制的限制,Web 应用程序的扩展性和性能问题一直是互联网服务提供商的痛点。
JSON Web Token(JWT)是一种应对以上问题的解决方案,它可以在客户端和服务器之间完全脱离服务器的状态,提供更加灵活和安全的身份认证和授权机制。在本文中,我们将介绍如何在 Node.js 中实现基于 JWT 的身份认证和授权机制。
JWT 基础知识
JWT 由三部分组成:
- Header:包含了标识令牌类型和签名算法等信息。
- Payload:包含了被传输的数据和一些元数据(如:到期时间,发行者等)。
- Signature:使用密钥对 Header 和 Payload 进行签名。
JWT 的生成流程可以简述为:
- 在服务器端创建 Payload 数据。
- 使用 Header,Payload 和 Secret(对称加密)或公钥/私钥(非对称加密)生成 Signature。
- 返回 JWT 令牌给客户端。
客户端接收到 JWT 后,需要将其存储在本地并将其传递回服务器。服务器通过公钥/私钥或共享秘钥将唯一的身份验证信息解密,并允许用户访问应用程序的受保护部分。
JWT 的优点:
- 状态无关(Stateless):不需要在服务器端存储任何信息,因此所有当前和过去的会话将不会对 Web 应用程序的性能和可伸缩性产生影响。
- 安全防护:使用签名机制保护传输的数据和元数据不被篡改。
- 支持跨域请求(CORS)。
实现基于 JWT 的身份认证和授权机制
安装依赖模块
我们需要安装 jsonwebtoken, body-parser 和 express 模块来生成和处理 JWT,解析 POST 请求和提供 Web 服务器。
npm install jsonwebtoken body-parser express --save
生成 JWT
我们在登录或认证时使用 JWT。当用户成功登录时,服务器凭借用户的信息生成 JWT 并将其返回给客户端。
-- -------------------- ---- ------- ----- --- - ------------------------ ----- ------- - ------------------- ----- --- - ---------- -- ------------ ----- ----- - - - --------- ------- --------- -------------- - -- ------------------------ ------------------ ----- ---- -- - ----- ---------- --------- - --------- -- ---- ----- ---- - ------------ -- - ------ ---------- --- -------- -- ---------- --- --------- --- -- ------ - -- -- --- ------------------- --------------- ------------ ----------- ------- ----- ------ -- - ---------- ----- --- --- - ---- - ----------------------------- -------------- - ---
这里我们使用了 jsonwebtoken
模块生成 JWT。该库提供了 sign
方法来生成 JWT。第一个参数是一个 JS 对象,也是 JWT 的第二部分即 Payload,存储了用户的信息。第二个参数是一个密钥字符串,用来对 JWT 进行签名。第三个参数是一个对象,用于设置 JWT 的一些元数据,如过期时间等。
身份验证和授权
在客户端发起请求时,客户端将包含 JWT 令牌作为请求的一部分(通常是 HTTP 请求头)。服务器将检查令牌的有效性,并检查用户对所请求的资源是否有足够的访问权限。
我们将创建一个 authenticateToken
函数来处理身份验证和授权。该函数接收一个请求对象和一个响应对象,并检查请求头中是否包含 JWT 令牌。如果包含,则仔细验证令牌是否有效或是否已过期。如果令牌是有效的,则继续处理请求,否则返回 401 错误。
-- -------------------- ---- ------- -------- ---------------------- ---- ----- - ----- ---------- - ----------------------------- ----- ----- - ---------- -- ------------------ ------ -- ------ -- ----- ------ -------------------- -- ------- --- ----------------- ------------ ----- -------- -- - -- ----- ------ -------------------- -- ---------- --- -------- - -------- -- ----- ------- --- -------- ---------- ------- --- -
在我们的示例中,我们将密钥字符串设为 secretkey
,实际使用时,请将其替换为更安全的密码。
使用 authenticateToken
函数,我们可以轻松管理针对请求的授权限制,只需在需要访问受保护的数据时将次函数作为中间件使用即可。
app.get('/customers', authenticateToken, (req, res) => { res.json(customers.filter(c => { return c.username === req.user.username; })); });
在我们的示例中,我们获取 customers 列表数据并仅返回属于当前用户的客户数据。一个用户只能访问其自己的客户数据。
结论
在 Node.js 中使用 JWT 实现身份认证和授权机制是一种非常强大和灵活的解决方案。使用 JWT,我们可以轻松地安全地管理用户身份验证和授权,并提供无状态媒介,从而提高 Web 应用程序的性能和可伸缩性。在下一次构建 Web 应用程序时,请考虑使用 JWT,它将极大地简化和提高您的应用程序的安全性和维护性。
示例代码
您可以在 GitHub 上找到一个完整的示例程序:jwt-node-example。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6733f2d00bc820c5824556ee