OAuth 2.0 和 JWT 简介:它们是什么以及为什么需要它们?
\n现代 Web 应用程序很少能脱离授权系统。无论是通过 Google 登录、访问 API 还是在您的 Node.js 应用程序中保护路由,您都需要 OAuth 2.0 和 JWT(JSON Web 令牌)。这些技术已成为客户端和服务器之间安全数据交换的事实标准。
\n在本文中,我们将分析 OAuth 2.0 和 JWT 的工作原理,并用 JavaScript (Node.js) 编写一个简单的授权系统。本材料面向初学者开发者,因此我们将从理论到实践,并提供详细的代码示例。
\n\n第一部分:什么是 OAuth 2.0 以及它是如何工作的?
\nOAuth 2.0 是一种授权协议,它允许应用程序在不传输密码的情况下获取对用户资源的有限访问权限。想象一下,您想通过您的 Google 帐户登录一个网站。OAuth 2.0 正是负责这个过程。
\nOAuth 2.0 中的主要角色
\n- \n
- 资源所有者 — 拥有数据的用户。 \n
- 客户端 — 您的应用程序(例如,Node.js 服务器)。 \n
- 授权服务器 — 颁发令牌的服务器(例如,Google、GitHub)。 \n
- 资源服务器 — 存储用户数据的服务器。 \n
典型的 OAuth 2.0 流程(授权码授权类型)
\n- \n
- 用户点击“通过 Google 登录”。 \n
- 应用程序将用户重定向到 Google 的授权服务器。 \n
- 用户给予同意。 \n
- Google 将
授权码返回给应用程序服务器。 \n - 服务器将此代码交换为
访问令牌。 \n - 服务器使用访问令牌来访问用户数据。 \n
在实践中,对于简单的应用程序,通常使用 JWT 作为访问令牌的格式。
\n\n第二部分:JWT — 结构和原理
\nJWT(JSON Web 令牌) 是一种以 JSON 对象形式在各方之间传输信息的紧凑且自包含的方式。令牌经过签名,因此无需访问数据库即可验证。
\nJWT 的结构
\nJWT 由三部分组成,用点 (.) 分隔:
header.payload.signature\n- \n
- 头部 — 包含令牌类型和签名算法(例如,HS256)。 \n
- 有效载荷 — 数据(声明),例如,用户 ID、角色、有效期。 \n
- 签名 — 使用密钥创建的签名。 \n
解码后的 JWT 示例
\n{\n "alg": "HS256",\n "typ": "JWT"\n}\n.\n{\n "sub": "1234567890",\n "name": "John Doe",\n "iat": 1516239022,\n "exp": 1516242622\n}\n.\n[signature]\n重要提示:有效载荷未加密,仅经过签名。切勿在 JWT 中存储机密数据(密码)!
\n\n第三部分:在 Node.js 中实现 JWT 授权
\n现在让我们进入实践。我们将使用 Express.js 创建一个带有 JWT 授权的简单 REST API。为此,我们需要 jsonwebtoken 和 bcryptjs 库。
步骤 1:安装依赖项
\nnpm init -y\nnpm install express jsonwebtoken bcryptjs dotenv\nnpm install --save-dev nodemon\n步骤 2:基本服务器设置
\n// server.js\nrequire('dotenv').config();\nconst express = require('express');\nconst jwt = require('jsonwebtoken');\nconst bcrypt = require('bcryptjs');\n\nconst app = express();\napp.use(express.json());\n\nconst users = []; // 在实际项目中 — 数据库\n\nconst PORT = process.env.PORT || 3000;\nconst JWT_SECRET = process.env.JWT_SECRET || 'mysecretkey123';\n\napp.listen(PORT, () => {\n console.log(`Server running on port ${PORT}`);\n});