Bạn bao nhiêu lần phải bấm "Forgot Password"? Với Magic Link, User không cần nhớ mật khẩu. Họ chỉ cần nhớ Email.
1. Magic Link hoạt động thế nào?
- User: Nhập email
alice@example.comvào form Login. - Server:
- Tạo một Token bí mật (random string), thời hạn 5-10 phút.
- Lưu Token vào DB (kèm trạng thái "Pending").
- Gửi Email chứa link:
https://app.com/verify?token=xyz123.
- User: Mở Email, bấm Link.
- Server:
- Kiểm tra Token
xyz123có hợp lệ không. - Nếu OK -> Xóa Token -> Tạo Session đăng nhập thật cho User.
- Kiểm tra Token
Ưu điểm:
- UX Đỉnh: Không cần nhớ pass. Không cần gõ phím nhiều.
- Bảo mật: Không bao giờ lộ password (vì làm gì có password mà lộ!).
Nhược điểm:
- Phụ thuộc Email: Nếu Email server chậm, user không vào được.
- Email Hijacking: Nếu hacker vào được Gmail của Alice, hắn vào được mọi App dùng Magic Link của Alice.
2. Triển khai với NextAuth
NextAuth hỗ trợ sẵn EmailProvider.
Config (auth.ts)
ts:
import EmailProvider from "next-auth/providers/email";
export const { handlers, auth } = NextAuth({
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER, // SMTP Server (Gmail/SendGrid/Resend)
from: "noreply@myapp.com",
}),
],
adapter: PrismaAdapter(prisma), // Cần Database để lưu Token tạm thời
});Database Schema (Prisma)
Cần bảng VerificationToken để lưu token tạm.
prisma:
model VerificationToken {
identifier String // Email của user
token String @unique
expires DateTime
@@unique([identifier, token])
}3. Same Device Flow (Bẫy UX)
Vấn đề:
- User mở App trên Laptop.
- Nhập Email.
- Mở Email trên Điện thoại -> Bấm Link.
- -> Điện thoại đăng nhập thành công. Nhưng Laptop vẫn đang chờ!
Giải pháp (Polling):
- Trên Laptop, sau khi gửi email, Client phải liên tục hỏi Server (Polling mỗi 2s): "Token này được verify chưa?".
- Khi user bấm link trên điện thoại -> Server đánh dấu Token là "Verified".
- Lần Polling tiếp theo -> Server báo "Verified rồi" -> Laptop tự động đăng nhập.
Kết luận
Magic Link cực kỳ phù hợp cho B2B SaaS (nơi user dùng email công ty và check mail thường xuyên). Tuy nhiên với App giải trí/Social, user thường lười check mail -> Passkeys (Bài sau) sẽ là lựa chọn tốt hơn.