Vì sao cookie và session lại bị lẫn khi test flow đăng nhập nhiều tài khoản

Test tính năng cần hai tài khoản, kiểu A nhắn tin cho B, A chuyển tiền cho B, A kết bạn B. Cách thường làm là đăng nhập A xong rồi đăng nhập B trên cùng một browser. Kết quả quen thuộc: A bị đăng xuất bất ngờ, request mang cookie của B trong lúc tưởng đang là A, logout bên này bên kia vẫn còn nguyên. Nhiều người kết luận ngay là “app bị lỗi session”, nhưng phần lớn trường hợp lẫn đến từ cách ta tổ chức môi trường test, không phải từ code.

Trình duyệt cất cookie ở đâu

Cookie không nằm rải rác trong hệ thống, mà nằm trong một cookie jar gắn với profile trình duyệt. Các tab thường chia sẻ jar đó, chế độ ẩn danh có jar tạm và đóng là mất. Cookie được giới hạn theo domain và path, còn localStorage thì tab nào cùng origin cũng đọc được. Nói ngắn gọn: hai tài khoản đăng nhập trên cùng một profile thì chia sẻ cùng một chỗ cất trạng thái . Server phân biệt phiên bằng cookie client gửi lên, client gửi cookie nào thì server hiểu bạn là ai.

“Lẫn” vì thế xảy ra theo mấy cách: đăng nhập B ghi đè cookie phiên của A cùng domain; token cũ vẫn nằm trong localStorage và bị JavaScript đọc lại sau khi tưởng đã đăng xuất; tab cũ của A vẫn giữ trạng thái cũ và ghi đè ngược lại; cache và service worker trả nguyên phản ứng của A cho tài khoản B. Trường hợp đáng chú ý: nếu test luồng OAuth, nhiều tab cùng chạy đăng nhập trên cùng origin có thể làm trạng thái authorization đè lên nhau, vì luồng này phụ thuộc vào state và redirect chứ không chỉ cookie. Hướng dẫn Browser-Based Apps của IETF có thảo luận riêng về việc nhiều tab cùng tồn tại, và dùng Service Worker làm lớp cách ly là một hướng làm được nhắc đến.

Cách hay dùng và vì sao chưa đủ

  • Ẩn danh : sạch mỗi lần mở, nhưng cũng mất sạch mỗi lần đóng, không giữ được phiên để test lại.

  • Xóa cookie : xóa luôn phiên đang cần giữ của tài khoản kia.

  • Hai browser khác nhau : Chrome cho A, Firefox cho B. Tách được nhưng không mở rộng, và hành vi hai browser không giống nhau, bug ở browser này chưa chắc xuất hiện ở browser kia.

  • Profile thường của Chrome hoặc Edge : tách được jar, nhưng quản lý thủ động, mở nhiều phiên song song thì cửa sổ lộn xộn.

Mô hình đúng: một danh tính test, một môi trường

Cách tổ chức gọn là coi mỗi tài khoản test là một danh tính riêng, mỗi danh tính một môi trường độc lập: cookie jar riêng, storage riêng, cache riêng. Khi test luồng hai chiều, cần hai phiên sống đồng thời , không phải lần lượt. BitBrowser cho phép mở nhiều profile cùng lúc trên một máy, mỗi profile giữ một phiên đăng nhập riêng, cửa sổ của A và cửa sổ của B chạy song song mà không đăng xuất lẫn nhau; bản miễn phí cho 10 profile, đủ cho hầu hết kịch bản test hai chiều, chi tiết thì mọi người xem trực tiếp trên site của họ. Một lưu ý khi chạy song song: đừng bật chế độ đồng bộ thao tác giữa các cửa sổ (Synchronize System), vì bản chất nó là điều khiển nhóm, thao tác ở A sẽ lan sang mọi cửa sổ, lúc đó B không còn là quan sát độc lập. Mở song song còn tiện để đối chiếu: cùng một thao tác, bên A thấy gì, bên B thấy gì, lệch là thấy ngay.

Phân biệt lẫn môi trường với lỗi thật của app

Không phải lần nào “lẫn” cũng là lỗi môi trường. Nếu logout bên A mà token của A vẫn gọi API được, đó là lỗi hủy phiên phía server. Nếu sau khi đăng nhập B, tab cũ của A vẫn hiển thị đúng dữ liệu của A thêm một lúc, có thể là cache hoặc state chưa bị vô hiệu. Nếu hai tài khoản khác nhau mà server trả về cùng một bộ dữ liệu, đó là lỗi phân quyền nghiêm trọng, không liên quan gì đến cookie jar. Cách kiểm: tái hiện lại trên hai môi trường thật sự tách biệt. Lỗi biến mất thì lỗi ở cách test, lỗi vẫn còn thì là bug của app, cứ mở ticket.

Quy trình gợi ý

Đặt tên profile theo tài khoản và mục đích test, ghi rõ trạng thái trước và sau mỗi vòng. Vòng test quan trọng thì ưu tiên phiên tạo mới. Ghi lại bước tái hiện kèm trạng thái phiên, vì nhiều bug chỉ hiện khi phiên bị buộc đăng nhập lại giữa chừng. Test trên hệ thống của bạn thì không vấn đề gì, trên hệ thống của người khác vẫn phải xin phép và tuân theo điều khoản của họ.

Mọi người có hay gặp trường hợp tưởng lỗi session hóa ra là do môi trường test, hoặc ngược lại? Kể lại để cùng rút kinh nghiệm.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?