08/10/2026 · VietTechies · Biên tập

Các ứng dụng trang đơn (SPA) sử dụng cơ chế xác thực PKCE (Proof Key for Code Exchange) thường gặp phải các sự cố bất đồng bộ ẩn khi chạy đồng thời trên nhiều thẻ (tab) trình duyệt. Dù các thư viện như okta-auth-js hỗ trợ đồng bộ hóa bộ nhớ cục bộ (local storage) và tự động gia hạn token, cấu hình mặc định lại thiếu ranh giới giao tác (transaction boundary) giữa các thẻ. Do mỗi thẻ đều vận hành một phiên bản SDK riêng trên cùng một bộ nhớ dùng chung, các thẻ dễ gửi yêu cầu làm mới token cùng lúc, dẫn đến nguy cơ làm hỏng trạng thái đăng nhập đang hoạt động.
Hạn chế về đồng thời khi dùng bộ nhớ SDK mặc định
Cấu hình okta-auth-js tiêu chuẩn cho phép kích hoạt các bộ lắng nghe sự kiện bộ nhớ (storage event listener) và trình hẹn giờ hết hạn tự động giữa các thẻ. Tuy nhiên, bộ nhớ cục bộ dùng chung không cung cấp cơ chế loại trừ tương hỗ (mutual exclusion) cho các yêu cầu mạng. Khi bộ hẹn giờ kích hoạt, mọi thẻ đang mở đều nỗ lực làm mới token cùng lúc. Việc đăng nhập thiếu phối hợp cũng có thể phát sinh các chu trình ủy quyền dư thừa, trong khi thao tác xóa sạch bộ nhớ một cách thiếu kiểm soát sẽ làm mất các mã kiểm tra (code verifier) PKCE đang hoạt động, gây gián đoạn quá trình đăng nhập trên các thẻ khác.
Phối hợp gia hạn token bằng Web Locks API
Để loại bỏ tình trạng race condition khi làm mới token, các ứng dụng có thể triển khai cơ chế bầu chọn tiến trình trưởng (leader election) thông qua Web Locks API. Việc chọn ra một thẻ đóng vai trò trưởng giúp đảm bảo chỉ có duy nhất một thẻ thực thi yêu cầu lấy token trong mỗi chu kỳ làm mới, trong khi các thẻ còn lại sẽ đợi thông tin xác thực cập nhật truyền qua sự kiện bộ nhớ. Thẻ trưởng được bầu chọn cần kiểm tra lại bộ nhớ bên trong phạm vi khóa (lock) trước khi gửi yêu cầu mạng, nhằm xác định xem thẻ giữ khóa trước đó đã hoàn tất việc làm mới hay chưa. Bên cạnh đó, ứng dụng nên giới hạn việc cập nhật token chỉ khi tài liệu đang hiển thị (visible document), tránh tình trạng các thẻ bị đóng băng hoặc chạy ngầm làm nghẽn yêu cầu.
Quản lý token và cấu hình nhà cung cấp định danh
Để phân phối trạng thái hiệu quả, ứng dụng cần định tuyến toàn bộ thao tác cập nhật thông tin xác thực qua tokenManager.setTokens(), đảm bảo các sự kiện bộ nhớ kích hoạt ổn định trên mọi tài liệu. Lập trình viên nên truy xuất token ngay tại thời điểm sử dụng bằng getIdToken() hoặc getAccessToken(), thay vì phụ thuộc vào trạng thái được lưu tạm (cached state) của thành phần giao diện. Về phía nhà cung cấp định danh (identity provider), việc thiết lập thời gian gia hạn xoay vòng token (rotation grace period) dài hơn khoảng thời gian chuyển giao khóa giữa các thẻ, đồng thời cấu hình khung thời gian không hoạt động (inactivity window) tối thiểu gấp ba lần thời hạn của access token sẽ giúp ngăn chặn việc chấm dứt phiên làm việc quá sớm. Nếu xảy ra lỗi invalid_grant, ứng dụng nên đọc lại bộ nhớ một lần nữa trước khi xác nhận thất bại xác thực.
Ảnh minh họa do AI tạo, không phải ảnh tư liệu.
Nguồn: Multi-Tab Session Sync in a PKCE SPA with `okta-auth-js`
