Next.js JWT 认证
介绍
在现代 Web 应用中,身份验证和授权是确保用户数据安全的关键功能。JSON Web Tokens (JWT) 是一种流行的身份验证机制,它允许服务器在用户登录后生成一个加密的令牌,客户端可以在后续请求中使用该令牌来验证身份。
Next.js 是一个强大的 React 框架,支持服务器端渲染(SSR)和静态生成(SSG)。结合 JWT,Next.js 可以轻松实现安全的身份验证流程。本文将带你从零开始,学习如何在 Next.js 中使用 JWT 进行身份验证。
什么是 JWT?
JWT 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它由三部分组成:
- Header:包含令牌类型(如 JWT)和使用的加密算法(如 HMAC SHA256)。
- Payload:包含声明(claims),例如用户 ID、角色和过期时间。
- Signature:用于验证令牌是否被篡改。
JWT 通常以以下格式呈现:
xxxxx.yyyyy.zzzzz
其中,xxxxx
是 Base64 编码的 Header,yyyyy
是 Base64 编码的 Payload,zzzzz
是 Signature。
在 Next.js 中实现 JWT 认证
1. 安装依赖
首先,我们需要安装一些依赖包来支持 JWT 的生成和验证:
npm install jsonwebtoken cookie
jsonwebtoken
:用于生成和验证 JWT。cookie
:用于在客户端和服务器之间安全地传输 JWT。
2. 创建登录 API 路由
在 Next.js 中,API 路由位于 pages/api
目录下。我们可以创建一个登录路由来生成 JWT:
// pages/api/login.js
import jwt from 'jsonwebtoken';
import { serialize } from 'cookie';
export default function handler(req, res) {
if (req.method === 'POST') {
const { username, password } = req.body;
// 模拟用户验证
if (username === 'admin' && password === 'password') {
// 生成 JWT
const token = jwt.sign({ username }, 'your-secret-key', { expiresIn: '1h' });
// 将 JWT 设置为 HTTP-only Cookie
res.setHeader('Set-Cookie', serialize('authToken', token, {
httpOnly: true,
secure: process.env.NODE_ENV !== 'development',
sameSite: 'strict',
maxAge: 3600, // 1 小时
path: '/',
}));
return res.status(200).json({ message: '登录成功' });
} else {
return res.status(401).json({ message: '用户名或密码错误' });
}
} else {
return res.status(405).json({ message: '仅支持 POST 请求' });
}
}
在实际应用中,请确保使用环境变量存储密钥(如 your-secret-key
),并避免硬编码敏感信息。
3. 验证 JWT
在受保护的 API 路由中,我们需要验证客户端发送的 JWT:
// pages/api/protected.js
import jwt from 'jsonwebtoken';
import { parse } from 'cookie';
export default function handler(req, res) {
const cookies = parse(req.headers.cookie || '');
const token = cookies.authToken;
if (!token) {
return res.status(401).json({ message: '未授权' });
}
try {
const decoded = jwt.verify(token, 'your-secret-key');
return res.status(200).json({ message: '访问成功', user: decoded.username });
} catch (error) {
return res.status(401).json({ message: '无效的令牌' });
}
}
4. 在客户端使用 JWT
在客户端,我们可以通过 fetch
或 axios
发送带有 JWT 的请求:
// 登录
const login = async () => {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'password' }),
});
const data = await response.json();
console.log(data);
};
// 访问受保护的资源
const fetchProtectedData = async () => {
const response = await fetch('/api/protected');
const data = await response.json();
console.log(data);
};
实际应用场景
用户登录与权限控制
假设你正在开发一个博客平台,用户需要登录后才能发布文章。通过 JWT,你可以在用户登录后生成一个令牌,并在用户访问发布页面时验证该令牌。如果令牌有效,用户将被允许发布文章;否则,用户将被重定向到登录页面。
总结
JWT 是一种简单而强大的身份验证机制,适用于现代 Web 应用。通过本文,你已经学会了如何在 Next.js 中实现 JWT 认证,包括生成令牌、验证令牌以及在客户端使用令牌。
附加资源与练习
- 练习:尝试扩展本文的示例,实现用户注册功能,并在注册后自动登录。
- 资源:
通过不断实践和探索,你将能够掌握更多关于身份验证与授权的知识!