Trả lời nhanh: Ba hướng xác thực người dùng và chọn theo loại ứng dụng: phiên đăng nhập lưu phía máy chủ là mặc định phù hợp cho ứng dụng web, vì thu hồi được ngay và ít lỗi cài đặt; thẻ ký JWT hợp cho ứng dụng di động và cho nhiều dịch vụ dùng chung, nhưng khó thu hồi trước hạn; dịch vụ bên ngoài tiết kiệm công lúc đầu, đổi lại phụ thuộc và tốn theo số người dùng. Lỗi phổ biến nhất không nằm ở chọn hướng mà ở cách lưu thông tin đăng nhập.
Xác thực là phần ai cũng phải làm và cũng là phần dễ sai theo cách nguy hiểm nhất. Bài này so ba hướng theo tiêu chí thực dụng, rồi liệt kê những lỗi hay gặp mà bạn nên soi lại trong dự án của mình ngay hôm nay.
Phiên đăng nhập lưu phía máy chủ
Cách cổ điển và vẫn là lựa chọn đúng cho phần lớn ứng dụng web. Máy chủ tạo một phiên, gửi cho trình duyệt một mã định danh qua cookie, và trạng thái thật nằm ở phía máy chủ.
Ưu điểm: thu hồi được ngay lập tức, chỉ cần xóa phiên; thông tin nhạy cảm không nằm ở phía người dùng; và ít chỗ để cài đặt sai.
Nhược điểm: máy chủ phải lưu trạng thái, nên khi chạy nhiều máy thì cần một nơi lưu chung, thường là bộ nhớ đệm dùng chung.
Ba thuộc tính cookie bắt buộc phải đặt:
Set-Cookie: phien=abc123; HttpOnly; Secure; SameSite=Lax; Path=/Thuộc tính đầu chặn mã JavaScript đọc được cookie, thứ hai buộc chỉ gửi qua kết nối mã hóa, thứ ba giảm rủi ro bị trang khác lợi dụng. Thiếu cái đầu tiên là lỗ hổng nghiêm trọng và cũng là lỗi hay gặp nhất.
Thẻ ký và khi nào nên dùng
Thẻ ký chứa thông tin về người dùng kèm chữ ký của máy chủ. Máy chủ không cần lưu gì, chỉ kiểm tra chữ ký.
Hợp khi: ứng dụng di động, vì cookie không tiện; nhiều dịch vụ cần cùng xác thực một người dùng; hoặc bạn muốn máy chủ không giữ trạng thái để dễ nhân bản.
Điểm yếu lớn nhất: thu hồi trước hạn rất khó. Thẻ đã phát thì có hiệu lực tới khi hết hạn, kể cả khi bạn vừa khóa tài khoản đó. Cách xử lý thông dụng là thẻ truy cập sống rất ngắn, ví dụ mười lăm phút, kèm thẻ làm mới sống dài hơn và lưu ở phía máy chủ để thu hồi được. Cách này lấy được ưu điểm của cả hai hướng, đổi lại phức tạp hơn.
Ba lỗi hay gặp: để thẻ trong nơi lưu trữ của trình duyệt mà mã JavaScript đọc được; đặt hạn quá dài cho tiện; và quên kiểm tra thuật toán ký khi xác minh.
Dịch vụ xác thực bên ngoài
Bạn giao toàn bộ phần đăng nhập, quên mật khẩu, đăng nhập bằng mạng xã hội cho một dịch vụ.
Đáng dùng khi: đội nhỏ muốn ra sản phẩm nhanh; cần đăng nhập bằng nhiều nhà cung cấp; hoặc cần các tính năng nâng cao như xác thực hai lớp mà bạn không muốn tự làm.
Cân nhắc: chi phí tăng theo số người dùng hoạt động, và dữ liệu người dùng nằm ngoài hệ thống của bạn. Với khách hàng doanh nghiệp hoặc cơ quan nhà nước, điểm thứ hai có thể là vấn đề, như đã bàn ở bài về tự kiểm soát hạ tầng.
Nếu chọn hướng này, hãy giữ một lớp trung gian trong mã nguồn để phần còn lại của ứng dụng không phụ thuộc trực tiếp vào nhà cung cấp. Nhờ vậy chuyển đổi về sau không phải sửa khắp nơi.
Những lỗi nguy hiểm nhất
Bốn lỗi này gây hậu quả nặng nhất và đều dễ tránh:
Lưu mật khẩu sai cách. Mật khẩu phải băm bằng thuật toán thiết kế riêng cho mật khẩu, không bao giờ mã hóa hai chiều và tuyệt đối không lưu thô. Dùng hàm có sẵn của nền tảng, đừng tự viết.
Không giới hạn số lần thử. Không có giới hạn thì một script đơn giản dò được mật khẩu yếu trong vài giờ. Giới hạn theo tài khoản và theo địa chỉ nguồn, kèm thời gian chờ tăng dần.
Thông báo lỗi tiết lộ quá nhiều. Trả về email không tồn tại giúp kẻ tấn công biết tài khoản nào có thật. Hãy trả về một thông báo chung cho cả hai trường hợp.
Đường khôi phục mật khẩu yếu. Mã đặt lại phải ngẫu nhiên đủ dài, hết hạn nhanh, và chỉ dùng được một lần. Rất nhiều hệ thống bảo vệ đăng nhập rất chặt rồi để lỏng đúng chỗ này.
Chọn cho dự án của bạn
- Ứng dụng web thuần, đội nhỏ: phiên lưu phía máy chủ. Ít chỗ sai nhất, thu hồi dễ nhất.
- Ứng dụng di động: thẻ truy cập ngắn hạn kèm thẻ làm mới lưu phía máy chủ.
- Web cộng di động dùng chung backend: vẫn có thể dùng phiên cho web và thẻ cho di động, không bắt buộc phải chọn một.
- Cần đăng nhập mạng xã hội và xác thực hai lớp ngay: cân nhắc dịch vụ ngoài để tiết kiệm thời gian ở giai đoạn đầu.
Dù chọn hướng nào, hãy ghi lại quyết định kèm lý do vào tài liệu trong repo. Đây là phần mà người kế nhiệm sẽ cần hiểu trước khi động vào, theo cách ghi trong bài về memory.
Và một lời khuyên chung: đừng tự viết phần mật mã. Dùng thư viện chuẩn của nền tảng bạn đang chạy, kể cả khi agent đề xuất một cách tự làm nghe rất gọn.
Bảng lỗi lưu thẻ đăng nhập và cách tránh
| Lỗi | Hậu quả | Cách tránh |
|---|---|---|
| Lưu thẻ ký ở nơi mã trên trình duyệt đọc được | Mã độc chèn vào trang đọc được thẻ | Lưu ở nơi mã trên trang không đọc được |
| Không có cách thu hồi thẻ trước hạn | Thẻ bị lộ vẫn dùng được tới khi hết hạn | Giữ danh sách thẻ đã thu hồi, hoặc dùng thẻ sống ngắn |
| Đặt thời hạn thẻ quá dài | Kéo dài cửa sổ nguy hiểm | Thẻ truy cập sống ngắn, thẻ làm mới sống dài hơn |
| Không kiểm chữ ký thẻ ở phía máy chủ | Ai cũng tự tạo thẻ được | Luôn kiểm chữ ký, không tin nội dung thẻ |
| Lưu mật khẩu không băm, hoặc băm bằng hàm cũ | Lộ cơ sở dữ liệu là lộ mọi mật khẩu | Dùng hàm băm mật khẩu chuyên dụng hiện hành |
Dòng thứ hai là điểm yếu cố hữu của cơ chế thẻ ký: máy chủ không giữ trạng thái nên không hủy được thẻ đã phát. Nếu hệ thống của bạn cần đăng xuất từ xa ngay lập tức, đây là yếu tố quyết định.
Bảng chọn cách xác thực theo kiến trúc
| Tình huống | Nên chọn | Vì sao |
|---|---|---|
| Ứng dụng web một khối, một máy chủ | Phiên đăng nhập lưu phía máy chủ | Đơn giản nhất, thu hồi được ngay |
| Ứng dụng di động gọi giao diện lập trình | Thẻ ký sống ngắn kèm thẻ làm mới | Thẻ ngắn hạn giảm rủi ro |
| Nhiều dịch vụ, nhiều ứng dụng khách | Thẻ ký, hoặc dịch vụ xác thực riêng | Không phải chia sẻ trạng thái phiên |
| Cần đăng nhập bằng tài khoản mạng xã hội hoặc tài khoản công ty | Dịch vụ xác thực bên ngoài | Tự làm phần này tốn và dễ sai |
| Đội nhỏ, không có ai chuyên bảo mật | Dịch vụ xác thực bên ngoài | Đây là phần dễ sai nhất khi tự làm |
Ba việc phải làm dù chọn cách nào
# 1. Gioi han so lan dang nhap sai, theo tai khoan VA theo dia chi mang# Khong co la mo cua cho viec do mat khau tu dong # 2. Bat xac thuc hai lop cho tai khoan quan tri, toi thieu # 3. Ghi nhat ky moi lan dang nhap thanh cong va that bai# Day la thu duy nhat cho biet co ai dang do khong # Kiem: thu dang nhap sai 20 lan lien tiepfor i in $(seq 1 20); do curl -o /dev/null -s -w "%{http_code} " -X POST https://api.tenmien.vn/dang-nhap \ -d '{"email":"[email protected]","password":"sai"}' -H "Content-Type: application/json"done; echo# Phai thay ma 429 xuat hienCâu hỏi thường gặp
Phiên hay thẻ ký tốt hơn?
Không có cái nào tốt hơn tuyệt đối. Phiên hợp cho ứng dụng web vì thu hồi được ngay và ít lỗi cài đặt. Thẻ ký hợp cho di động và cho nhiều dịch vụ dùng chung, nhưng bạn phải xử lý được chuyện thu hồi trước hạn.
Lưu thẻ ở đâu trong ứng dụng web?
Trong cookie có thuộc tính chặn JavaScript đọc, không phải trong nơi lưu trữ của trình duyệt. Nếu mã JavaScript đọc được thẻ thì một lỗ hổng chèn mã cũng đủ để kẻ tấn công lấy được nó.
Có nên tự viết phần xác thực không?
Phần luồng thì viết được, nhưng phần mật mã và băm mật khẩu thì luôn dùng thư viện chuẩn của nền tảng. Tự viết phần đó là nguồn của những lỗ hổng nghiêm trọng mà bạn không tự phát hiện ra.
Cần máy chủ thế nào cho hệ thống có nhiều người đăng nhập?
Phiên lưu ở bộ nhớ đệm dùng chung cần RAM, còn mỗi lần kiểm tra đăng nhập là một lượt đọc database. Ổ đĩa nhanh và đủ RAM quan trọng hơn số nhân xử lý với loại tải này.
