数据库知识篇

什么是用户认证与权限

"你是谁"和"你能做什么"

几乎所有应用都需要解决两个问题:

  1. 认证(Authentication):你是谁?——验证用户身份
  2. 授权(Authorization):你能做什么?——控制访问权限

💡 类比:认证就像门禁刷卡(证明你是这栋楼的住户),授权就像房间钥匙(住户能进自己的房间,但不能进别人的)。

加载图表中...

认证方式

1. 用户名 + 密码

最传统的方式:

加载图表中...

2. 第三方登录(OAuth)

用 GitHub、Google、微信等账号登录:

加载图表中...

3. 手机验证码

加载图表中...
认证方式优点缺点
用户名+密码简单通用用户容易忘记密码
第三方登录无需注册,体验好依赖第三方平台
手机验证码安全性高需要短信服务,有成本
邮箱验证免费体验较差

密码安全:千万不要明文存储!

加载图表中...
import bcrypt from "bcryptjs";

// 注册时:密码加密后存储
const hashedPassword = await bcrypt.hash("user_password", 10);
// 存储到数据库: "$2b$10$x8Kx..."

// 登录时:验证密码
const isValid = await bcrypt.compare("user_input", hashedPassword);
// true = 密码正确

Token 认证机制

现代应用最常用 JWT(JSON Web Token) 来管理登录状态:

加载图表中...
// 后端:生成 Token
import jwt from "jsonwebtoken";

const token = jwt.sign(
  { userId: user.id, email: user.email },  // 载荷
  process.env.JWT_SECRET,                   // 密钥
  { expiresIn: "7d" }                       // 7天过期
);

// 后端:验证 Token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
console.log(decoded.userId);  // 用户ID

权限控制

基于角色的权限(RBAC)

加载图表中...

API 路由中的权限检查

// middleware:验证登录状态
function requireAuth(handler) {
  return async (request) => {
    const token = request.headers.get("Authorization")?.replace("Bearer ", "");

    if (!token) {
      return Response.json({ error: "未登录" }, { status: 401 });
    }

    try {
      const user = jwt.verify(token, process.env.JWT_SECRET);
      return handler(request, user);
    } catch {
      return Response.json({ error: "Token无效" }, { status: 401 });
    }
  };
}

// middleware:验证管理员权限
function requireAdmin(handler) {
  return requireAuth(async (request, user) => {
    if (user.role !== "admin") {
      return Response.json({ error: "无权限" }, { status: 403 });
    }
    return handler(request, user);
  });
}

401 vs 403

状态码含义场景
401 Unauthorized未认证(没登录)没提供 Token
403 Forbidden未授权(没权限)登录了,但权限不够

Next.js + Supabase 认证实战

// 使用 Supabase 内置认证

// 注册
const { data, error } = await supabase.auth.signUp({
  email: "user@example.com",
  password: "secure_password",
});

// 登录
const { data, error } = await supabase.auth.signInWithPassword({
  email: "user@example.com",
  password: "secure_password",
});

// 获取当前用户
const { data: { user } } = await supabase.auth.getUser();

// GitHub 登录
await supabase.auth.signInWithOAuth({ provider: "github" });

// 保护 API 路由
export async function GET(request: Request) {
  const { data: { user }, error } = await supabase.auth.getUser();

  if (!user) {
    return Response.json({ error: "未登录" }, { status: 401 });
  }

  // 只返回当前用户的数据
  const { data } = await supabase
    .from("articles")
    .select("*")
    .eq("user_id", user.id);

  return Response.json(data);
}

安全清单

项目说明
✅ 密码必须哈希加密存储永远不要明文存储密码
✅ 使用 HTTPS防止传输过程被窃听
✅ Token 设置过期时间不要让 Token 永不过期
✅ 敏感操作要二次验证修改密码、删除账号等
✅ 防止SQL注入使用参数化查询
✅ 前端不存储敏感信息密码、密钥不要存在 localStorage

🎯 AI编程小贴士:实现用户认证系统是新手最头疼的事之一。直接告诉 AI"帮我用 Next.js + Supabase 实现完整的用户注册、登录、登出功能",它会帮你搞定从数据库到前端页面的所有代码。

小结

  • 认证验证"你是谁",授权控制"你能做什么"
  • 密码必须哈希加密存储(bcrypt),永远不要明文
  • JWT Token 是现代应用最常用的认证机制
  • 角色(RBAC) 管理不同用户的权限
  • 401 = 没登录,403 = 没权限
  • 推荐用 Supabase 等 BaaS 平台的内置认证,省时省力