Xác thực là gì? Đăng nhập, phiên làm việc và OAuth giải thích dễ hiểu
Xác thực là cách một ứng dụng xác nhận người dùng là ai, thường bằng cách kiểm tra điều gì đó họ biết (mật khẩu), điều gì đó họ có (mã gửi tới điện thoại hoặc email) hoặc một danh tính từ dịch vụ đáng tin cậy khác (như "Đăng nhập bằng Google"). Khi người dùng đã được xác thực, ứng dụng ghi nhớ họ bằng session hoặc token để họ không phải đăng nhập lại ở mỗi trang. Việc quyết định người dùng đã biết đó được phép làm gì là một bước riêng, gọi là phân quyền (authorization).
Vì sao điều này quan trọng khi bạn xây dựng bằng AI
Thêm đăng nhập là một trong những yêu cầu phổ biến nhất gửi tới công cụ xây dựng bằng AI, và cũng là một trong những việc dễ làm sai một cách tinh vi nhất. Trang đăng nhập thì đơn giản để tạo ra. Phần khó là mọi thứ xung quanh nó:
- Mật khẩu có được lưu an toàn không?
- Mỗi trang riêng tư và mỗi endpoint API có thực sự kiểm tra xem ai đang yêu cầu không?
- Một khách hàng đã đăng nhập có thể xem dữ liệu của khách hàng khác bằng cách đổi một con số trên URL không?
- Điều gì xảy ra khi ai đó quên mật khẩu?
Một ứng dụng có thể trông hoàn toàn an toàn nhưng lại thất bại ở cả bốn điểm trên. Hiểu các thành phần vận hành sẽ giúp bạn đặt đúng câu hỏi và kiểm tra đúng điều cần kiểm tra.
Một ví dụ đời thường
Hãy hình dung việc nhận phòng khách sạn.
Ở quầy lễ tân, bạn xuất trình giấy tờ tùy thân. Đó là xác thực: chứng minh bạn là ai. Nhân viên sau đó đưa cho bạn một thẻ từ. Thẻ đó là session của bạn: trong suốt thời gian lưu trú, bạn không cần xuất trình giấy tờ nữa, chỉ cần quẹt thẻ.
Thẻ mở được phòng của bạn, phòng gym và thang máy lên tầng của bạn, nhưng không mở được phòng của khách khác hay văn phòng nhân viên. Đó là phân quyền: danh tính của bạn được phép truy cập những gì. Nếu bạn làm mất thẻ, khách sạn có thể vô hiệu hóa nó tại quầy (thu hồi session). Khi trả phòng, thẻ ngừng hoạt động (đăng xuất, hoặc hết hạn).
"Đăng nhập bằng Google" giống như khách sạn chấp nhận một lá thư từ đối tác đáng tin cậy xác nhận "đây là người này", thay vì tự kiểm tra giấy tờ của bạn.
Các phương thức đăng nhập chính
| Phương thức | Cách hoạt động | Ưu điểm | Nhược điểm |
|---|---|---|---|
| Email + mật khẩu | Người dùng chọn mật khẩu; ứng dụng lưu hash của nó | Quen thuộc, không phụ thuộc bên ngoài | Bạn phải lưu hash an toàn và xử lý việc đặt lại mật khẩu |
| Liên kết ma thuật / mã dùng một lần | Ứng dụng gửi liên kết hoặc mã qua email để đăng nhập | Không có mật khẩu để bị rò rỉ hoặc quên | Phụ thuộc vào việc gửi email; đăng nhập chậm hơn |
| Đăng nhập mạng xã hội (OAuth / OpenID Connect) | Người dùng đăng nhập bằng Google, Apple, GitHub, v.v. | Nhanh với người dùng; bạn không lưu mật khẩu | Phải cấu hình với từng nhà cung cấp; người dùng không có các tài khoản đó thì không dùng được |
| Nhà cung cấp xác thực có sẵn | Một dịch vụ như Clerk, Auth0 hoặc Supabase Auth xử lý đăng ký, đăng nhập và đặt lại mật khẩu | Bạn bớt công việc bảo mật | Chi phí hàng tháng khi quy mô lớn; thêm một phụ thuộc |
| Đa yếu tố (MFA / 2FA) | Một bước kiểm tra thứ hai sau bước đầu, như mã từ ứng dụng xác thực | Khó bị xâm nhập hơn nhiều | Hơi phiền phức hơn một chút |
Mật khẩu nên được lưu như thế nào
Một ứng dụng an toàn không bao giờ lưu mật khẩu thật của bạn. Thay vào đó, nó lưu một hash: kết quả của một hàm một chiều biến mật khẩu thành một chuỗi cố định. Khi bạn đăng nhập, ứng dụng hash những gì bạn gõ và so sánh kết quả với hash đã lưu.
Hai chi tiết giúp việc này an toàn:
- Salt: một giá trị ngẫu nhiên được thêm vào mỗi mật khẩu trước khi hash, để hai người có cùng mật khẩu nhận được hash khác nhau, và các bảng tra cứu được tính sẵn trở nên vô dụng.
- Thuật toán chậm được thiết kế riêng cho mật khẩu: như Argon2, bcrypt hoặc scrypt. Các hàm hash đa dụng như MD5 hay SHA-256 quá nhanh nếu dùng đơn lẻ; kẻ tấn công có thể thử hàng tỷ lần đoán.
Hash không giống với mã hóa. Dữ liệu được mã hóa có thể giải mã bằng khóa; còn hash mật khẩu được thiết kế để hoàn toàn không thể đảo ngược.
Session so với token
Sau khi đăng nhập, ứng dụng cần nhận ra bạn trong mỗi yêu cầu. Có hai cách tiếp cận phổ biến.
| Session (cookie) | Token (ví dụ JWT) | |
|---|---|---|
| Trình duyệt giữ gì | Một ID session ngẫu nhiên trong cookie | Một token đã ký chứa thông tin người dùng và thời hạn |
| Trạng thái đăng nhập nằm ở đâu | Trên server, trong cơ sở dữ liệu hoặc kho lưu trữ | Ngay trong bản thân token |
| Đăng xuất một người khỏi mọi nơi | Dễ: xóa session trên server | Khó hơn: token vẫn hợp lệ cho đến khi hết hạn, trừ khi bạn duy trì danh sách chặn |
| Thường dùng cho | Ứng dụng web truyền thống | API, ứng dụng di động, các dịch vụ giao tiếp với nhau |
Với cookie, ba thiết lập quan trọng là: HttpOnly (JavaScript trên trang không đọc được cookie), Secure (chỉ gửi qua HTTPS) và SameSite (hạn chế việc gửi cookie trong các yêu cầu từ trang khác). Lưu token trong localStorage của trình duyệt là cách làm phổ biến nhưng để lộ chúng cho mọi đoạn script chạy trên trang.
OAuth và "Đăng nhập bằng Google"
OAuth 2.0 là một chuẩn cho ủy quyền có chọn lọc: nó cho phép ứng dụng nhận quyền truy cập giới hạn vào tài khoản của bạn trên một dịch vụ khác, chẳng hạn đọc lịch Google của bạn, mà không bao giờ thấy mật khẩu Google của bạn. Bạn được chuyển đến Google, phê duyệt các quyền cụ thể (gọi là scope), và Google cấp cho ứng dụng một token chỉ dùng cho các quyền đó.
Bản thân OAuth được thiết kế để cấp quyền truy cập, không phải để xác định bạn là ai. OpenID Connect (OIDC) là một lớp xây trên OAuth 2.0 để bổ sung khả năng định danh, và đó là cơ chế mà "Đăng nhập bằng Google" hay "Đăng nhập bằng Apple" sử dụng. Để thiết lập, bạn đăng ký ứng dụng với nhà cung cấp và nhận một client ID và client secret; secret phải được giữ trên server của bạn.
Ví dụ minh họa: đăng nhập cho cổng khách hàng
Giả sử bạn đang xây một cổng thông tin nơi khách hàng của một công ty thiết kế xem các dự án và hóa đơn của họ.
- Xác thực: khách hàng đăng nhập bằng email và liên kết ma thuật, nên không có mật khẩu nào cần quản lý. Nhân viên công ty đăng nhập bằng tài khoản Google Workspace.
- Vai trò: mỗi người dùng có một vai trò:
clienthoặcstaff. - Quy tắc phân quyền:
| Hành động | Khách hàng | Nhân viên |
|---|---|---|
| Xem dự án của công ty mình | Có | Có |
| Xem dự án của công ty khác | Không | Có |
| Tải tệp lên một dự án | Chỉ dự án của mình | Có |
| Đánh dấu hóa đơn đã thanh toán | Không | Có |
- Nơi thực thi: trên server, cho mọi yêu cầu. Server tra cứu người dùng đã đăng nhập, rồi chỉ trả về các dự án mà
project.company_idkhớp với công ty của người dùng. Ẩn nút "Đánh dấu đã thanh toán" là chưa đủ; chính endpoint đó phải từ chối.
Giải thích các thuật ngữ thường gặp
| Thuật ngữ | Ý nghĩa |
|---|---|
| Authentication (AuthN) - Xác thực | Xác nhận một người là ai. |
| Authorization (AuthZ) - Phân quyền | Quyết định họ được phép làm gì. |
| Session | Việc ứng dụng ghi nhớ bạn đang đăng nhập, giữa các yêu cầu. |
| Cookie | Một mẩu dữ liệu nhỏ mà trình duyệt gửi lại cho trang web trong mỗi yêu cầu. |
| JWT | JSON Web Token: một token gọn, đã ký, mang các thông tin như ID người dùng và thời hạn. |
| Role / permission - Vai trò / quyền | Nhãn như admin hoặc member quyết định quyền truy cập. |
| MFA / 2FA | Yêu cầu một bằng chứng thứ hai, như mã từ ứng dụng xác thực. |
| SSO | Đăng nhập một lần: một lần đăng nhập (thường là tài khoản công ty) dùng cho nhiều ứng dụng. |
| 401 so với 403 | "Bạn là ai?" (chưa xác thực) so với "Bạn không được phép làm việc đó" (không đủ quyền). |
Lỗi thường gặp và những hiểu lầm
- Chỉ kiểm tra quyền ở phía trang. Nếu trình duyệt ẩn một nút nhưng API không kiểm tra, bất kỳ ai cũng có thể gọi API trực tiếp.
- Tin tưởng ID lấy từ URL.
/invoices/1042phải kiểm tra rằng hóa đơn 1042 thuộc về người dùng đã đăng nhập. - Tự viết mật mã. Hãy dùng các thư viện hoặc nhà cung cấp đã được biết đến; đừng để AI tự phát minh cơ chế hash.
- Đặt lại mật khẩu yếu. Liên kết đặt lại nên chỉ dùng được một lần, hết hạn nhanh và không tiết lộ việc một email có tài khoản hay không.
- Nhầm lẫn đăng nhập của ứng dụng với đăng nhập của công cụ xây dựng. Người dùng ứng dụng của bạn tách biệt với tài khoản của bạn trên công cụ bạn dùng để xây dựng.
- Không giới hạn tần suất đăng nhập. Nếu không có giới hạn, kẻ tấn công có thể thử mật khẩu vô hạn lần.
Nên yêu cầu công cụ xây dựng AI của bạn điều gì
- "Thêm đăng ký và đăng nhập bằng [một thư viện hoặc nhà cung cấp được biết đến]. Đừng tự viết cơ chế hash mật khẩu."
- "Lưu mật khẩu đã hash bằng bcrypt hoặc Argon2."
- "Dùng cookie HttpOnly và Secure cho session."
- "Thêm vai trò: admin và member. Liệt kê mọi endpoint và vai trò nào được gọi chúng."
- "Đảm bảo trên server rằng người dùng chỉ có thể đọc và sửa bản ghi của chính họ. Sau đó cho tôi xem bạn đã kiểm tra như thế nào."
- "Thêm đặt lại mật khẩu với liên kết dùng một lần, hết hạn sau một giờ."
- "Giới hạn số lần thử đăng nhập."
Sau đó tự kiểm tra: tạo hai tài khoản và thử truy cập dữ liệu của tài khoản này khi đang đăng nhập bằng tài khoản kia. Hướng dẫn thêm đăng nhập và danh sách kiểm tra bảo mật của chúng tôi đi sâu hơn.
Xác thực trong Mythex
Mythex không cung cấp sản phẩm xác thực dựng sẵn cho người dùng ứng dụng của bạn; bạn chọn một cách tiếp cận, ví dụ email và mật khẩu được lưu trong cơ sở dữ liệu của dự án, hoặc SDK của một nhà cung cấp dịch vụ, rồi yêu cầu tác tử thêm nó. Khóa của nhà cung cấp được đặt trong secret của dự án, không đưa vào chat. Điều này tách biệt với cách bạn đăng nhập vào chính Mythex. Công thức trong tài liệu về thêm đăng nhập cho ứng dụng có một prompt khởi đầu bạn có thể điều chỉnh, và API là gì giải thích nơi các kiểm tra phía server đó nằm.
Câu hỏi thường gặp
Xác thực (authentication) khác phân quyền (authorization) như thế nào?
Xác thực kiểm tra bạn là ai, ví dụ bằng cách xác minh mật khẩu. Phân quyền quyết định bạn được phép làm gì sau khi đã biết bạn là ai, chẳng hạn bạn có được xem trang quản trị hay chỉnh sửa lịch đặt của người khác không. Ứng dụng cần cả hai.
OAuth là gì?
OAuth 2.0 là một chuẩn cho phép ứng dụng nhận quyền truy cập giới hạn vào tài khoản của bạn trên một dịch vụ khác mà không cần thấy mật khẩu của bạn. Nút "Đăng nhập bằng Google" dùng OpenID Connect, một lớp định danh xây dựng trên OAuth 2.0, nhờ đó ứng dụng biết bạn là ai qua Google.
Ứng dụng của tôi có nên lưu mật khẩu không?
Tuyệt đối không lưu dưới dạng đọc được. Nếu bạn dùng đăng nhập bằng email và mật khẩu, mật khẩu phải được lưu dưới dạng hash có salt, tạo bằng một thuật toán chậm được thiết kế riêng cho mật khẩu, như Argon2 hoặc bcrypt. Nhiều ứng dụng tránh vấn đề này bằng cách dùng nhà cung cấp xác thực có sẵn, đăng nhập mạng xã hội hoặc liên kết đăng nhập gửi qua email.
Ứng dụng nên dùng phiên (session) hay token?
Cả hai đều dùng được. Session lưu trạng thái đăng nhập trên server và gửi cho trình duyệt một ID ngẫu nhiên trong cookie, dễ thu hồi. Token như JWT tự mang thông tin đã ký, phù hợp với API và ứng dụng di động, nhưng khó hủy trước khi hết hạn. Với một ứng dụng web thông thường, session dựa trên cookie là lựa chọn mặc định hợp lý.