🌐 下一站:Next.js 的身份认证之旅

208 阅读3分钟

🛤️ 序章:Web 身份的烦恼

在古老的 Web1.0 时代,用户只是点点超链接,服务器只需把 HTML 塞给你就行。
但 Web2.0 来了,用户要登录、购物、发动态…… 服务器必须知道“你是谁” 。于是,**会话管理(Session Management)**登场了。

  • Session:像是俱乐部的会员卡,进门亮一下,服务员就知道你是谁。
  • JWT:像是随身携带的一份签名文件,别人一看签名就知道是真的。

🏰 第一幕:Session 管理

1. 工作原理

  1. 用户输入账号密码 → 服务器验证成功。
  2. 服务器在内存/数据库里开一个小房间(Session),里面放着 userIdrole 等信息。
  3. 服务器给用户的浏览器发一个 Set-Cookie,内容是一个 Session ID(例如 abc123)。
  4. 之后用户的每个请求都会带上这个 Cookie,服务器就能在房间里找到对应信息。
浏览器 🧑 ——(Cookie: abc123)——> 服务器 🖥️ ——[Session房间abc123]——> 用户信息

2. 优缺点

  • ✅ 简单直观,安全性好(Session 存在服务器)。
  • ❌ 服务器要维护大量 Session,分布式部署时需要共享存储(Redis 等)。

🚀 第二幕:JWT(JSON Web Token)

1. 工作原理

JWT 像是一份签好名的“电子通行证”。它通常由三部分组成:

  • Header(头部):声明类型和加密算法。
  • Payload(载荷):用户数据,比如 id: 42, role: admin
  • Signature(签名):用服务器的密钥签出来,证明这份票是真的。

最终长得像这样:

xxxxx.yyyyy.zzzzz

2. 流程图

用户登录成功 🧑 
       ↓
服务器签发 JWT 🎫
       ↓
浏览器保存 (LocalStorage / Cookie)
       ↓
每次请求带上 JWT
       ↓
服务器验证签名 ✅
       ↓
允许访问资源

3. 优缺点

  • ✅ 无需服务器保存状态,分布式系统特别方便。
  • ❌ JWT 一旦签发就不可撤销(除非黑名单机制),而且 Token 可能比较大。

🧩 第三幕:Next.js 中的实践

1. 使用 JWT

在 Next.js API Route 中,我们可以这样生成和验证 JWT:

// lib/auth.js
import jwt from "jsonwebtoken";

const SECRET = "super-secret-key"; // 实际项目要放在环境变量里

export function signToken(user) {
  return jwt.sign({ id: user.id, role: user.role }, SECRET, { expiresIn: "1h" });
}

export function verifyToken(token) {
  try {
    return jwt.verify(token, SECRET);
  } catch (err) {
    return null;
  }
}
// app/api/login/route.js
import { signToken } from "@/lib/auth";

export async function POST(req) {
  const { username, password } = await req.json();

  if (username === "alice" && password === "wonderland") {
    const token = signToken({ id: 1, role: "admin" });
    return new Response(JSON.stringify({ token }), { status: 200 });
  }

  return new Response("Unauthorized", { status: 401 });
}

2. 使用 Session(例如 next-auth

// app/api/auth/[...nextauth]/route.js
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

const handler = NextAuth({
  providers: [
    CredentialsProvider({
      async authorize(credentials) {
        if (credentials.username === "alice" && credentials.password === "wonderland") {
          return { id: 1, name: "Alice", role: "admin" };
        }
        return null;
      },
    }),
  ],
});

export { handler as GET, handler as POST };

🎭 第四幕:文学化总结

  • Session 就像“国王的账本”,所有信息都记在宫殿的档案室里。
  • JWT 就像“骑士的印章文书”,骑士拿着它能在王国里自由通行。

在现代 Web 开发中,我们常常需要在 便利性安全性 之间做出取舍。
而 Next.js 给了我们一个舞台,让 Session 和 JWT 都能优雅登场。


📌 彩蛋:何时选谁?

  • 单体应用 + 安全优先 → Session
  • 分布式微服务 + 无状态 API → JWT

🧑‍💻 写到这里,咖啡也凉了。
如果你能理解 Session 和 JWT 的差别,那你就比大多数初学者更接近 Web 后端的本质。
下一步,就是实践与踩坑了。