Hướng dẫn tích hợp
Thêm «Đăng nhập bằng Tutu» vào sản phẩm của bạn trong bốn bước, dùng OAuth2 + PKCE.
Bốn bước tích hợp
Frontend bắt đầu đăng nhập
Tạo một instance bằng createTutuId({ baseUrl, clientId }) từ @tutu/id-sdk và gọi idSdk.startLogin() khi nhấp. SDK tạo cặp PKCE và chuyển hướng đến trang ủy quyền TutuId.
Người dùng ủy quyền trên TutuId
Trên màn hình đồng ý /oauth/authorize người dùng nhấn «Cho phép» (tự bỏ qua nếu đã ủy quyền). Sau khi TutuId kiểm tra client_id và danh sách cho phép redirect_uri, nó chuyển hướng về /auth/callback của bạn kèm mã ủy quyền.
Trang callback lấy code
Tại /auth/callback gọi idSdk.completeCallback() để lấy { code, codeVerifier }. Chuyển hai giá trị này cho backend của bạn; đừng bao giờ đổi token trực tiếp trong trình duyệt.
Backend đổi token → tạo tài khoản
Backend của bạn đổi code + codeVerifier lấy access_token, gọi /userinfo để nhận { sub, email, emailVerified, ... }, ánh xạ hoặc tạo tài khoản cục bộ theo sub, rồi phát hành phiên của riêng bạn.
★ Phòng chống chiếm đoạt tài khoản (bắt buộc)
Backend của bạn chỉ được liên kết hoặc tạo tài khoản cục bộ theo sub (ID tài khoản duy nhất). Chỉ khi emailVerified === true bạn mới được liên kết tài khoản cục bộ hiện có theo email; nếu không, hãy tạo tài khoản riêng và để trống email.
Vì sao: kẻ tấn công có thể đăng ký trước một tài khoản Tutu bằng email của nạn nhân; hợp nhất theo email chưa xác minh sẽ trao tài khoản cục bộ của nạn nhân. Đây là lằn ranh đỏ mức CVE.
Tham chiếu API của SDK
@tutu/id-sdk · thuần phía client, không phụ thuộc (cần Web Crypto + sessionStorage).
createTutuId({ baseUrl, clientId, redirectUri? }) Tạo một instance SDK. redirectUri mặc định là ${location.origin}/auth/callback, tự thích ứng dev/prod.
startLogin(scope?) Tạo cặp PKCE và chuyển hướng đến trang ủy quyền, bắt đầu «Đăng nhập bằng Tutu».
trySilentLogin(scope?) Đăng nhập im lặng: nếu có phiên trung tâm và đã ủy quyền trước đó, đổi mã liền mạch; nếu không, lập tức trở về trạng thái đã đăng xuất (không làm gián đoạn người dùng).
completeCallback() Phân tích kết quả trên trang callback: thành công trả về { code, codeVerifier }, thất bại/hủy trả về { error }.
logoutEverywhere(returnTo?) Đăng xuất phiên trung tâm, dây chuyền đăng xuất mọi sản phẩm trong bộ, rồi quay lại returnTo.
Muốn xem thử hoạt động trước?