如何使用 JWT(JSON Web Tokens)进行身份验证
在现代 web 应用程序中,身份验证是一个至关重要的环节。在众多身份验证方法中,JWT(JSON Web Tokens)因其简单易用、高效安全等优点而受到广泛青睐。本文将详细介绍什么是 JWT、如何使用 JWT 进行身份验证,并提供相应的示例代码。
什么是 JWT?
JWT,即 JSON Web Token,是一种基于 JSON 格式的开放标准(RFC 7519),用于在网络应用环境中安全地传输信息。JWT 的结构由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
-
头部:一般由两部分组成,表示令牌的类型(JWT)和所使用的签名算法(如 HMAC SHA256 或 RSA)。
-
载荷:包含声明(Claims)。声明是关于实体(通常是用户)及其他数据的声明。根据不同的需求,载荷可以自定义一般信息,如用户 ID、角色等。
-
签名:通过将头部和载荷进行编码,然后使用密钥生成的签名,确保信息未被篡改。
综上所述,一个 JWT 的结构如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
为什么使用 JWT 进行身份验证?
-
无状态:JWT 可以在客户端存储用户信息,不需要在服务器端保存会话信息,适合分布式系统。
-
有效性:JWT 采用 JSON 格式,易于解析和使用。
-
灵活性:可以自定义载荷,存储用户身份和其他信息。
-
安全性:使用密钥进行签名,确保传输的信息未被修改。
如何使用 JWT 进行身份验证
以下是使用 JWT 进行身份验证的基本步骤:
- 用户使用用户名和密码登录。
- 服务器验证用户身份,如果验证成功,则生成 JWT 并将其返回给客户端。
- 客户端将 JWT 存储在本地(如
localStorage
或sessionStorage
)。 - 调用需要身份验证的 API 时,将 JWT 附在请求头中发送至服务器。
- 服务器验证 JWT 的合法性,合法则请求成功,反之则返回未授权。
示例代码
接下来,我们将通过一个简单的示例,演示如何使用 Node.js 和 Express 来实现 JWT 身份验证。
1. 安装依赖
首先,我们需要安装 Express 和 jsonwebtoken 库。在项目目录下运行以下命令:
npm install express jsonwebtoken body-parser cors
2. 创建 Express 服务器
创建一个名为 server.js
的文件,并添加以下代码:
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const PORT = 3000;
const SECRET_KEY = 'your-very-secret-key';
app.use(cors());
app.use(bodyParser.json());
// 模拟用户数据库
let users = [
{ id: 1, username: 'john', password: 'password123' },
{ id: 2, username: 'jane', password: 'password456' }
];
// 登录接口
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);
if (user) {
const token = jwt.sign({ id: user.id, username: user.username }, SECRET_KEY, { expiresIn: '1h' });
return res.json({ token });
} else {
return res.status(401).json({ message: 'Invalid credentials' });
}
});
// 受保护的路由
app.get('/protected', (req, res) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(403).json({ message: 'No token provided' });
}
jwt.verify(token, SECRET_KEY, (error, decoded) => {
if (error) {
return res.status(401).json({ message: 'Unauthorized' });
}
return res.json({ message: 'Access granted', user: decoded });
});
});
// 启动服务器
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
3. 客户端示例
下面是一个简单的 HTML 文件(index.html
),用于与上述服务器交互:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JWT Authentication</title>
<script>
async function login() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const response = await fetch('http://localhost:3000/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password })
});
const data = await response.json();
if (response.ok) {
localStorage.setItem('token', data.token);
alert('Login successful!');
} else {
alert(data.message);
}
}
async function accessProtected() {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:3000/protected', {
method: 'GET',
headers: {
'Authorization': token,
}
});
const data = await response.json();
if (response.ok) {
alert(`Message: ${data.message}, User: ${JSON.stringify(data.user)}`);
} else {
alert(data.message);
}
}
</script>
</head>
<body>
<h1>JWT Authentication</h1>
<input type="text" id="username" placeholder="Username" />
<input type="password" id="password" placeholder="Password" />
<button onclick="login()">Login</button>
<button onclick="accessProtected()">Access Protected Route</button>
</body>
</html>
运行示例
- 启动服务器:在命令行中运行
node server.js
启动 Express 服务器。 - 打开
index.html
文件,输入用户名和密码(如john
和password123
),点击登录。 - 登录成功后,点击“Access Protected Route”按钮以访问受保护的路由。
总结
JWT 是一种在 web 应用中进行身份验证的高效、安全的方式。其无状态的特性使其非常适合分布式系统,同时也为开发者提供了灵活性。通过本文的示例代码,你可以轻松实现一个基本的基于 JWT 的身份验证系统。