跳到主要内容

Next.js JWT 认证

介绍

在现代 Web 应用中,身份验证和授权是确保用户数据安全的关键功能。JSON Web Tokens (JWT) 是一种流行的身份验证机制,它允许服务器在用户登录后生成一个加密的令牌,客户端可以在后续请求中使用该令牌来验证身份。

Next.js 是一个强大的 React 框架,支持服务器端渲染(SSR)和静态生成(SSG)。结合 JWT,Next.js 可以轻松实现安全的身份验证流程。本文将带你从零开始,学习如何在 Next.js 中使用 JWT 进行身份验证。


什么是 JWT?

JWT 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它由三部分组成:

  1. Header:包含令牌类型(如 JWT)和使用的加密算法(如 HMAC SHA256)。
  2. Payload:包含声明(claims),例如用户 ID、角色和过期时间。
  3. Signature:用于验证令牌是否被篡改。

JWT 通常以以下格式呈现:

xxxxx.yyyyy.zzzzz

其中,xxxxx 是 Base64 编码的 Header,yyyyy 是 Base64 编码的 Payload,zzzzz 是 Signature。


在 Next.js 中实现 JWT 认证

1. 安装依赖

首先,我们需要安装一些依赖包来支持 JWT 的生成和验证:

bash
npm install jsonwebtoken cookie
  • jsonwebtoken:用于生成和验证 JWT。
  • cookie:用于在客户端和服务器之间安全地传输 JWT。

2. 创建登录 API 路由

在 Next.js 中,API 路由位于 pages/api 目录下。我们可以创建一个登录路由来生成 JWT:

javascript
// 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:

javascript
// 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

在客户端,我们可以通过 fetchaxios 发送带有 JWT 的请求:

javascript
// 登录
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 认证,包括生成令牌、验证令牌以及在客户端使用令牌。


附加资源与练习

  1. 练习:尝试扩展本文的示例,实现用户注册功能,并在注册后自动登录。
  2. 资源

通过不断实践和探索,你将能够掌握更多关于身份验证与授权的知识!