RESTful API 是现代 Web 应用的常见设计模式,它很好地支持跨平台、跨语言的数据交换。但对于 API 的安全保证,用户认证和鉴权则是一大难点。传统的方式包括 Cookie、Session 和 Basic Auth 等,但它们都存在不同的弊端,比如 CSRF、无法支持跨域等问题。JWT 能够优雅地解决这些问题。
JWT 简介
JWT(JSON Web Token)是一种轻量、安全、可携带的标识符。它由三个部分组成:Header、Payload 和 Signature,采用 Base64 编码后使用句号分隔符组成的字符串。
其中,Header 包含了算法和类型信息,例如:
{ "alg": "HS256", "typ": "JWT" }
Payload 包含了实际的用户信息和其他自定义数据,例如:
{ "sub": "12345", "name": "John Doe", "iat": 1516239022 }
Signature 是将 Header 和 Payload 进行 HMAC 或 RSA 等算法加密后的结果,以确保信息的完整性和真实性。
JWT 的优点
相比传统的用户认证方式,JWT 具有以下优点:
- 无状态:不需要在服务端存储 Session,也不需要依赖 Cookie。
- 跨域:由于 JWT 存储在客户端,因此能够跨域调用 API。
- 可扩展:可以自定义 Payload 中的数据,方便实现更复杂的功能需求。
- 安全:利用了数字签名技术,有效保障了信息的完整性和真实性。
使用 JWT 实现用户认证和鉴权
下面我们演示如何使用 JWT 实现 RESTful API 的用户认证和鉴权。
生成 JWT Token
在用户登录成功后,需要服务器返回一个带有 JWT Token 的结果。我们可以使用 jsonwebtoken
库来生成该 Token。示例代码:
-- -------------------- ---- ------- ----- --- - ------------------------ ----- ------- - - ---- -------- ----- ----- ----- ---- --------------------- - ----- -- ----- ------ - ---------------- ----- ----- - ----------------- ------- - ---------- ---- ---
在这里,我们首先定义一个 Payload 对象,包含了用户的信息和签发时间。然后,使用 jwt.sign()
方法,传入 Payload 对象、秘钥和 Token 过期时间(可选),生成符合标准的 JWT Token。
解析 JWT Token
在后续的 API 访问中,客户端使用该 Token 发送请求,而服务器需要进行 Token 的验证和解析。同样,我们可以使用 jsonwebtoken
库来完成这个过程。示例代码:
-- -------------------- ---- ------- ----- ---------- - ----- ---- ----- -- - ----- ----- - --------------------------------- ------ ----- ------ - ---------------- --- - ----- ------- - ----------------- -------- -------- - -------- ------- - ----- ------- - ---------------------- -------- ------ ----- --- - -- --------------------- ----------- ----- ---- -- - ---------- -------- ------------ --- ---
在这里,我们首先定义一个 verifyFunc
中间件,用于 Token 验证和解析的逻辑。我们从请求头中取出 Token,使用 jwt.verify()
方法,传入 Token 和秘钥,并使用 try-catch
语句包裹,避免解码失败导致程序异常退出。若验证成功,则将用户信息保存在 req.user
中,方便后续逻辑的访问。若验证失败,则返回 401
状态码和错误信息。
在 app.get
方法中,我们加入了 verifyFunc
中间件,表示该路径需要 Token 的认证和鉴权,只有通过验证的用户才能访问。若未通过验证,则会返回失败信息。
总结
本文介绍了 JWT 技术,以及如何利用其实现 RESTful API 的用户认证和鉴权。通过使用 JWT 技术,我们能够在安全性、跨域和扩展性等方面取得优势,降低 API 开发的实现成本和维护难度。希望本文能够对前端开发者有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f14c3ff6b2d6eab3b22633