OAuth 2.0 和 JWT 授权在 JavaScript 中的实践
现代 Web 应用程序很少能脱离身份验证和授权系统。两个最流行的标准——OAuth 2.0 和 JWT(JSON Web 令牌)——通常一起使用来创建安全且可扩展的解决方案。在本文中,我们将通过实际代码示例,讲解如何在 JavaScript (Node.js) 中实现 OAuth 2.0 和 JWT 授权。
本材料对于希望更深入理解令牌和委托访问机制的新手和经验丰富的开发者都很有用。
什么是 OAuth 2.0 和 JWT?
OAuth 2.0 是一种授权协议,允许应用程序在不传递用户凭据的情况下,获取对用户资源的有限访问权限。例如,您可以通过 Google 或 GitHub 登录网站——这就是 OAuth 2.0。
JWT(JSON Web 令牌) 是一种紧凑的令牌格式,包含编码数据(payload)和签名。JWT 用于在各方(客户端和服务器)之间传递信息并验证其真实性。
在组合中,OAuth 2.0 充当令牌颁发协议,而 JWT 作为访问令牌本身的格式。
服务器配置和依赖项安装
首先,我们创建一个基于 Express.js 的简单服务器并安装必要的包:
npm init -ynpm install express jsonwebtoken dotenv cors axiosnpm install --save-dev nodemon项目结构:
server.js— 服务器主文件.env— 环境变量middleware/auth.js— 用于验证 JWT 的中间件routes/auth.js— 身份验证路由
实现 JWT 授权
我们从基本的 JWT 令牌生成和验证开始。创建 server.js:
const express = require('express');const jwt = require('jsonwebtoken');require('dotenv').config();
const app = express();app.use(express.json());
const SECRET_KEY = process.env.JWT_SECRET || 'my_secret_key';
// 生成令牌function generateToken(user) { const payload = { id: user.id, email: user.email, role: user.role }; return jwt.sign(payload, SECRET_KEY, { expiresIn: '1h' });}
// 登录路由示例app.post('/login', (req, res) => { const { email, password } = req.body; // 此处应在数据库中进行验证 const user = { id: 1, email, role: 'user' }; const token = generateToken(user); res.json({ token });});
// 用于验证令牌的中间件function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) { return res.status(401).json({ error: '未提供令牌' }); }
jwt.verify(token, SECRET_KEY, (err, user) => { if (err) { return res.status(403).json({ error: '无效的令牌' }); } req.user = user; next(); });}
// 受保护的路由app.get('/profile', authenticateToken, (req, res) => { res.json({ message: '访问已授权', user: req.user });});
app.listen(3000, () => console.log('服务器已在端口 3000 上启动'));通过 Google 集成 OAuth 2.0
现在,我们使用 Google 作为提供商添加 OAuth 2.0。创建 routes/auth.js:
const express = require('express');const axios = require('axios');const jwt = require('jsonwebtoken');const router = express.Router();
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET;const REDIRECT_URI = 'http://localhost:3000/auth/google/callback';const JWT_SECRET = process.env.JWT_SECRET;
// 初始路由