Chắc hẳn có không ít anh em thời sinh viên nếu code Bài tập lớn cùng team mà thấy bản thân code gà hơn những bạn trong nhóm, là sẽ hay "xung phong" nhận code chức năng Login/Logout.
Mặc dù đến lúc học môn liên quan đến bảo mật cũng được các thầy dạy về những trường hợp tấn công vào chức năng Login/Logout, nhưng phải đến khi thực sự đi làm, được tiếp xúc với team chịu trách nhiệm quản lý riêng phần Login/Logout cho cả hệ sinh thái sản phẩm của công ty, tôi mới hiểu nếu phải tự triển khai những chức năng trước đây "mình nghĩ" là đơn giản này nó phức tạp và nhiều trường hợp cần xử lý đến mức độ nào.
Đương nhiên là ngày nay đã có những bên thứ ba họ xử lý sẵn vấn đề này (ví dụ: Auth0, Firebase Authentication, AWS Cognito) và chúng ta chỉ cần tích hợp vào là xong.
Nhưng nếu anh em tò mò, hoặc công ty, dự án của anh em muốn tự triển khai phần này, thì hãy cùng xem thử những công việc cần làm là gì nhé:
🚨 LƯU Ý:
KHÔNG PHẢI dự án nào cũng cần thực hiện tất cả những chức năng mà tôi liệt kê ở dưới đây.
Hãy cân nhắc kỹ trước khi áp dụng dựa vào quy mô của dự án, hãy tham khảo từ những anh Senior hoặc SA có nhiều kinh nghiệm để quyết định.
Tôi chỉ liệt kê theo kinh nghiệm cá nhân từ những gì bản thân biết được.
1. Login
-
Input validation:
- Kiểm tra dữ liệu đầu vào như định dạng email/username và password trước khi gửi lên server.
-
Password security:
- Bắt buộc sử dụng mật khẩu mạnh (tối thiểu 8 ký tự, bao gồm chữ hoa, chữ thường, số, ký tự đặc biệt)
- Password lưu trong database phải được hash (bằng bcrypt, Argon2, scrypt,...) chứ không được lưu plain text.
-
Session creation (nếu dùng session):
- Sau khi xác thực thành công, tạo session phía server và gửi session ID về client thông qua cookie.
-
JWT issuance (nếu dùng token-based auth):
- Nếu dùng JWT, cần tạo access token (và có thể là refresh token) sau khi xác thực, gửi về client để lưu trữ.
-
Set secure cookies:
- Nếu lưu token/session ID trong cookie, cần đặt
HttpOnly
,Secure
,SameSite
để tăng bảo mật.
- Nếu lưu token/session ID trong cookie, cần đặt
-
CSRF protection:
- Nếu dùng cookie để lưu auth info, cần kết hợp CSRF token để tránh các cuộc tấn công CSRF.
-
Two-Factor Authentication (2FA):
- Hỗ trợ xác thực 2 bước, gửi OTP qua email/SMS hoặc dùng app xác thực như Google Authenticator
-
"Remember me" support:
- Nếu có, lưu refresh token/token sống lâu để duy trì đăng nhập giữa các phiên.
-
Account lockout policy:
- Tạm khóa tài khoản sau
X
lần đăng nhập sai liên tiếp để ngăn brute force attack. Ví dụ các ngân hàng thường khóa tài khoản sau5
lần đang nhập sai liên tiếp.
- Tạm khóa tài khoản sau
-
Rate limiting:
- Ví dụ giới hạn số lần login trong một khoảng thời gian.
-
CAPTCHA:
- Thêm CAPTCHA sau vài lần login sai liên tục.
-
Device Fingerprinting:
- Thu thập đặc điểm thiết bị (user-agent, canvas, WebGL, timezone, ...)
- Hash thành device ID.
- Nếu phát thiết bị lạ => Gửi email cảnh báo, yêu cầu xác minh OTP.
-
GeoIP Tracking:
- Phát hiện đăng nhập từ IP quốc gia lạ.
- Gửi email cảnh báo, yêu cầu xác minh OTP.
-
Session management:
- Hạn chế thời gian sống của session.
- Regenerate session ID sau khi đăng nhập thành công để tránh session fixation.
-
Frontend error feedback:
- Hiển thị lỗi cụ thể (sai mật khẩu, tài khoản không tồn tại, tài khoản bị khóa,...) cho người dùng.
-
Logging:
- Ghi log tất cả hành vi đăng nhập thành công/thất bại vào hệ thống log để phục vụ audit hoặc bảo mật (ghi nhận id, email, thời điểm, IP, thiết bị,...)
2. Logout
-
Session invalidation:
- Khi người dùng logout, phải xóa session phía server hoàn toàn để ngăn chặn việc reuse session đã hết hạn.
-
CSRF protection:
- Khi gọi API logout, cần chống CSRF, ví dụ như yêu cầu thêm CSRF token hợp lệ được gửi cùng request.
-
Token revocation (nếu dùng token-based auth):
- Nếu sử dụng JWT cho xác thực, cần có cơ chế để đánh dấu token là không hợp lệ (revoked), ví dụ thông qua danh sách blacklist trong Redis hoặc đặt thời gian sống rất ngắn cho token và dùng refresh token.
-
Clear cookies:
- Xóa toàn bộ cookies chứa thông tin xác thực (access token, refresh token, session ID, ...) ở phía client sau khi logout.
-
Redirect to login page hoặc homepage:
- Sau khi logout thành công, người dùng nên được điều hướng đến trang đăng nhập hoặc trang chủ tùy theo yêu cầu UX.
-
Frontend state cleanup:
- Xóa dữ liệu người dùng khỏi state/Redux/Context/... trên client để tránh hiển thị thông tin nhạy cảm sau khi logout.
-
Invalidate refresh token:
- Nếu sử dụng cơ chế refresh token, cần đảm bảo token này cũng bị hủy hoặc xóa khỏi cơ sở dữ liệu.
-
Tùy chọn logout tất cả sessions:
- Cho phép logout toàn bộ thiết bị (all sessions), một thiết bị cụ thể nào đó, hoặc chỉ logout trên thiết bị hiện tại.
-
Frontend error feedback:
- Nhớ try catch để thông báo lỗi cho người dùng đề phòng trường hợp logout thất bại.
-
Logging:
- Ghi lại tất cả hành vi thành công/thất bại khi logout vào hệ thống log để phục vụ audit hoặc bảo mật (ghi nhận id, email, thời điểm, IP, thiết bị,...)
3. Forgot Password
-
Email/username verification:
- Kiểm tra xem email hoặc username có tồn tại trong hệ thống trước khi gửi link set lại mật khẩu.
-
Rate limiting và abuse protection:
- Giới hạn số lần yêu cầu quên mật khẩu từ một IP hoặc cho một email để tránh spam, phá hoại.
-
Generate secure token:
- Tạo token ngẫu nhiên, đủ độ dài và khó đoán (thường từ 32-64 ký tự), dùng một lần để reset mật khẩu.
-
Token expiration:
- Token set lại mật khẩu phải có thời hạn sử dụng ngắn (ví dụ: 15 phút) để giảm rủi ro bị lợi dụng.
-
Gửi email kèm reset link:
- Gửi email chứa link set lại mật khẩu, thường có dạng
https://example.com/reset-password?token=...
.
- Gửi email chứa link set lại mật khẩu, thường có dạng
-
Lưu trữ token ở server side (nếu không sử dụng JWT):
- Lưu token đã tạo vào cơ sở dữ liệu kèm thời gian hết hạn, gắn với user tương ứng.
-
Form reset password:
- Giao diện form set lại mật khẩu phải đảm bảo:
- Token còn hợp lệ.
- Mật khẩu mới phải đủ mạnh (kèm xác nhận lại)
- Có xác thực CSRF nếu dùng cookie.
- Giao diện form set lại mật khẩu phải đảm bảo:
-
Token one-time usage:
- Sau khi người dùng set lại mật khẩu thành công, token phải bị vô hiệu hóa ngay lập tức.
-
Password security:
- Mật khẩu mới bắt buộc cũng phải sử dụng mật khẩu mạnh (tối thiểu 8 ký tự, bao gồm chữ hoa, chữ thường, số, ký tự đặc biệt)
- Password lưu trong database phải được hash (bằng bcrypt, Argon2, scrypt,...) chứ không được lưu plain text.
-
Thông báo với user sau khi reset:
- Gửi email, thông báo cho người dùng khi mật khẩu đã được thay đổi để họ kiểm soát các hành vi bất thường.
-
Tùy chọn logout tất cả sessions:
- Có thể có thêm tùy chọn cho phép click vào sẽ logout tất cả các session hiện tại sau khi set lại mật khẩu để tăng bảo mật.
-
Frontend error feedback:
- Thông báo lỗi cụ thể (ví dụ: token hết hạn, mật khẩu quá yếu,...) thân thiện với người dùng.
-
Logging:
- Ghi lại hành vi reset mật khẩu thành công/thất bại vào hệ thống log để phục vụ audit hoặc bảo mật (ghi nhận id, email, thời điểm, IP, thiết bị,...)
4. Register
-
Input validation:
- Kiểm tra định dạng email, độ mạnh mật khẩu, username không chứa ký tự đặc biệt, xác nhận 2 lần nhập mật khẩu khớp nhau,... ở cả phía client và server.
-
Duplicate check:
- Kiểm tra email hoặc username đã tồn tại trong hệ thống chưa để tránh đăng ký trùng.
-
Password security:
- Bắt buộc sử dụng mật khẩu mạnh (tối thiểu 8 ký tự, bao gồm chữ hoa, chữ thường, số, ký tự đặc biệt)
- Password lưu trong database phải được hash (bằng bcrypt, Argon2, scrypt,...) chứ không được lưu plain text.
-
Email verification:
- Gửi email xác thực tài khoản (kèm link hoặc mã xác nhận)
-
Rate limiting & bot protection:
- Giới hạn số lần đăng ký từ một IP, kết hợp với CAPTCHA/reCAPTCHA để ngăn bot tạo tài khoản ảo.
-
Username/email normalization:
- Chuyển email về dạng chuẩn (lowercase, bỏ khoảng trắng đầu/cuối,...) để so sánh đúng khi kiểm tra trùng.
-
Set default user role/status:
- Gán role mặc định (vd:
user
) và trạng thái xác minh emailunverified
nếu chưa xác minh.
- Gán role mặc định (vd:
-
Tạo các thực thể liên quan sau khi đăng ký:
- Tạo các thực thể liên quan như hồ sơ người dùng (
profile
), giỏ hàng trống (cart
), danh sách yêu thích (favorites
), ... tùy theo nghiệp vụ của ứng dụng.
- Tạo các thực thể liên quan như hồ sơ người dùng (
-
Gửi welcome email:
- Gửi email chào mừng (kèm hướng dẫn xác minh, sử dụng, hỗ trợ,...) nếu cần
-
Secure session/token issuance:
- Sau khi đăng ký thành công, có thể tự động đăng nhập người dùng bằng cách tạo session hoặc cấp access token.
-
CSRF protection:
- Nếu dùng cookie để lưu auth/session, cần bảo vệ form đăng ký bằng CSRF token.
-
Email/phone confirmation reminder UI:
- Hiển thị thông báo yêu cầu xác minh tài khoản (nếu áp dụng) kèm button gửi lại mã xác thực/email.
-
Terms of Service & Privacy Policy agreement:
- bắt buộc người dùng phải đồng ý với điều khoản sử dụng và chính sách bảo mật trước khi đăng ký.
-
Frontend error feedback:
- Thông báo lỗi cụ thể (ví dụ: mật khẩu quá yếu, tài khoản đã tồn tại, ...) thân thiện với người dùng.
-
Logging:
- Ghi lại hành vi đăng ký vào hệ thống log để phục vụ audit hoặc bảo mật (ghi nhận id, email, thời điểm, IP, thiết bị,...)
Một số lưu ý thực tế khi triển khai
Vấn đề | Lưu ý |
---|---|
Người dùng đổi mạng wifi, hoặc chuyển sang 3G, 4G | Trao đổi với người có kinh nghiệm để xem xét những trường hợp nào thay đổi IP phải thông báo cho người dùng, hay là thông báo tất cả mọi trường hợp |
VPN | Cho phép người dùng xác nhận "Đó là tôi" nếu dùng VPN gây nhầm lẫn |
Private mode | Fingerprint có thể bị lỗi => fallback về IP + user-agent nếu cần |
Quyền riêng tư | Phải thông báo rõ cho người dùng về thu thập fingerprint/IP trong Privacy Policy |
UX mượt mà | Không ép xác minh quá nhiều, tránh gây khó chịu cho người dùng |
Hi vọng bài viết này của tôi đã giúp các bạn có cái nhìn rộng hơn về chức năng Login, Logout, Forgot Password, Register trong thực tế
Hẹn gặp lại các bạn ở những bài viết tiếp theo!
Nếu anh em thấy hay thì ủng hộ tôi 1 follow + 1 upvote + 1 bookmark + 1 comment cho bài viết này tại Mayfest 2025 nhé. Còn nếu bài viết chưa hữu ích thì tôi cũng hi vọng anh em để lại những góp ý thẳng thắn để tôi có thể học hỏi và cải thiện kiến thức của mình. Cảm ơn anh em nhiều!
🙋🏻♂️ Một số kênh mạng xã hội khác mà tôi dùng để chia sẻ và trao đổi với anh em kiến thức về ngành CNTT và lập trình:
-
Group "Khi nào giỏi lập trình thì đổi tên 🫢": https://www.facebook.com/groups/gioilaptrinhthidoiten
-
Page "CLB Lập trình - THPT Ngọc Tảo": https://www.facebook.com/clb.it.ngoctao/
-
TikTok "CLB Lập trình - THPT Ngọc Tảo": https://www.tiktok.com/@clb.it.ngoctao/
-
Youtube "Tờ Mờ Sáng học Lập trình": https://www.youtube.com/@tmsanghoclaptrinh/