数据库知识篇
什么是用户认证与权限
"你是谁"和"你能做什么"
几乎所有应用都需要解决两个问题:
- 认证(Authentication):你是谁?——验证用户身份
- 授权(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 平台的内置认证,省时省力