Điều gì tạo nên trải nghiệm đăng xuất tốt?

Kenji Baheux
Kenji Baheux

Đăng xuất

Khi người dùng đăng xuất khỏi một trang web, tức là họ thể hiện mong muốn thoát khỏi hoàn toàn trải nghiệm được cá nhân hoá cho người dùng. Vì vậy, điều quan trọng là phải tuân thủ mô hình tư duy của người dùng một cách chặt chẽ nhất có thể. Ví dụ: một trải nghiệm đăng xuất phù hợp cũng phải tính đến mọi thẻ mà người dùng có thể đã mở trước khi quyết định đăng xuất.

Chìa khoá của một trải nghiệm đăng xuất tuyệt vời có thể được tóm tắt là tính nhất quán trên các khía cạnh trực quan và trạng thái của trải nghiệm người dùng. Hướng dẫn này đưa ra lời khuyên cụ thể về những điều cần chú ý và cách để có trải nghiệm đăng xuất hiệu quả.

Các điểm chính cần cân nhắc

Khi triển khai chức năng đăng xuất trên trang web của bạn, hãy chú ý đến các khía cạnh sau để đảm bảo quá trình đăng xuất diễn ra suôn sẻ, an toàn và trực quan:

  • Trải nghiệm người dùng đăng xuất rõ ràng và nhất quán: Cung cấp nút hoặc đường liên kết đăng xuất rõ ràng và nhất quán, dễ nhận dạng và dễ truy cập trên toàn bộ trang web. Tránh sử dụng nhãn không rõ ràng hoặc ẩn chức năng đăng xuất trong các trình đơn, trang con hoặc các vị trí khó hiểu khác.
  • Lời nhắc xác nhận: Triển khai lời nhắc xác nhận trước khi hoàn tất quá trình đăng xuất. Điều này có thể giúp ngăn người dùng vô tình đăng xuất và cho phép người dùng xem xét lại nếu họ thực sự cần đăng xuất (ví dụ: nếu họ chăm chỉ khoá thiết bị bằng mật khẩu mạnh hoặc cơ chế xác thực khác).
  • Xử lý nhiều thẻ: Nếu người dùng đã mở nhiều trang của cùng một trang web trong nhiều thẻ, hãy đảm bảo rằng việc đăng xuất khỏi một thẻ cũng sẽ cập nhật tất cả các thẻ đang mở khác trên trang web đó.
  • Chuyển hướng đến một trang đích bảo mật: Sau khi đăng xuất thành công, hãy chuyển hướng người dùng đến một trang đích bảo mật cho biết rõ rằng họ không còn đăng nhập nữa. Tránh chuyển hướng người dùng đến các trang có thông tin được cá nhân hoá. Tương tự, hãy đảm bảo rằng các thẻ khác không còn phản ánh trạng thái đã đăng nhập nữa. Ngoài ra, hãy đảm bảo bạn hiện không tạo lệnh chuyển hướng mở mà những kẻ tấn công có thể lợi dụng.
  • Xoá phiên: Sau khi người dùng đã đăng xuất, hãy xoá hoàn toàn mọi dữ liệu nhạy cảm về phiên, cookie hoặc tệp tạm thời được liên kết với phiên của người dùng. Điều này ngăn hành vi truy cập trái phép vào thông tin người dùng hoặc hoạt động tài khoản, đồng thời ngăn trình duyệt khôi phục các trang có thông tin nhạy cảm từ nhiều bộ nhớ đệm của trình duyệt, cụ thể là bộ nhớ đệm cho thao tác tiến/lùi.
  • Xử lý lỗi và phản hồi: Cung cấp thông báo lỗi hoặc phản hồi rõ ràng cho người dùng nếu có vấn đề khi họ đăng xuất. Thông báo cho người dùng về mọi rủi ro bảo mật tiềm ẩn hoặc việc rò rỉ dữ liệu nếu quy trình đăng xuất không thành công.
  • Những điểm cần lưu ý về khả năng hỗ trợ tiếp cận: Đảm bảo rằng người dùng khuyết tật có thể truy cập vào cơ chế đăng xuất, bao gồm cả những người sử dụng các công nghệ hỗ trợ như trình đọc màn hình hoặc điều hướng bằng bàn phím.
  • Khả năng tương thích trên nhiều trình duyệt: Thử nghiệm chức năng đăng xuất trên nhiều trình duyệt và thiết bị để đảm bảo tính năng này hoạt động nhất quán và đáng tin cậy.
  • Liên tục giám sát và cập nhật: Thường xuyên giám sát quy trình đăng xuất để phát hiện lỗ hổng bảo mật hoặc lỗ hổng bảo mật tiềm ẩn. Triển khai các bản cập nhật và bản vá kịp thời để giải quyết mọi vấn đề phát hiện được.
  • Liên kết danh tính: Nếu người dùng đăng nhập bằng danh tính được liên kết, hãy xem việc đăng xuất khỏi nhà cung cấp danh tính có được hỗ trợ và cần thiết hay không. Ngoài ra, nếu nhà cung cấp danh tính hỗ trợ tính năng tự động đăng nhập, hãy nhớ ngăn chặn việc này.

NÊN

  • Nếu bạn vô hiệu hoá một cookie trên máy chủ trong quy trình đăng xuất (hoặc các quy trình thu hồi quyền truy cập khác), hãy nhớ xoá cookie đó trên thiết bị của người dùng.
  • Xoá mọi dữ liệu nhạy cảm mà bạn có thể đã lưu trữ trên thiết bị của người dùng: cookie, localStorage, sessionStorage, indexedDB, CacheStorage và bất kỳ kho dữ liệu cục bộ nào khác.
  • Đảm bảo rằng mọi tài nguyên có chứa dữ liệu nhạy cảm (cụ thể là các tài liệu HTML) đều được trả về cùng với tiêu đề HTTP Cache-control: no-store để trình duyệt không lưu trữ các tài nguyên này trong bộ nhớ vĩnh viễn (ví dụ: trên ổ đĩa). Tương tự, các lệnh gọi XHR/fetch trả về dữ liệu nhạy cảm cũng phải đặt tiêu đề HTTP Cache-Control: no-store để ngăn việc lưu vào bộ nhớ đệm.
  • Đảm bảo rằng mọi thẻ đã mở trên thiết bị của người dùng đều là thẻ mới nhất có chức năng thu hồi quyền truy cập phía máy chủ.

Dọn dẹp dữ liệu nhạy cảm sau khi đăng xuất

Sau khi đăng xuất, hãy cân nhắc việc xoá dữ liệu nhạy cảm tạm thời và dữ liệu nhạy cảm được lưu trữ trên máy. Việc tập trung vào dữ liệu nhạy cảm có động lực là việc xoá mọi thứ sẽ dẫn đến trải nghiệm người dùng kém hơn nhiều vì người dùng này rất có thể quay lại. Ví dụ: nếu bạn xoá tất cả dữ liệu được lưu trữ cục bộ, thì người dùng sẽ phải xác nhận lại lời nhắc đồng ý sử dụng cookie và thực hiện các quy trình khác như thể họ chưa từng truy cập vào trang web của bạn.

Cách xoá cookie

Trên phản hồi cho trang xác nhận trạng thái đã đăng xuất, hãy đính kèm tiêu đề HTTP Set-Cookie để xoá mọi cookie liên quan đến hoặc chứa dữ liệu nhạy cảm. Hãy đặt giá trị expires thành một ngày trong quá khứ và đặt giá trị của cookie thành một chuỗi trống để đo lường hiệu quả.

Set-Cookie: sensitivecookie1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
Set-Cookie: sensitivecookie2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
...

Tình huống không có mạng

Mặc dù phương pháp được mô tả ở trên là đủ cho các trường hợp sử dụng chung, nhưng phương pháp này sẽ không hiệu quả nếu người dùng đang làm việc ngoại tuyến. Bạn nên xem xét việc yêu cầu hai cookie để theo dõi trạng thái đăng nhập: một cookie bảo mật chỉ dành cho HTTPS và một cookie thông thường có thể truy cập qua JavaScript. Nếu người dùng đang cố đăng xuất khi không có mạng, thì bạn có thể xoá cookie JavaScript và tiến hành các hoạt động dọn dẹp khác nếu có thể. Nếu có trình chạy dịch vụ, thì bạn cũng nên tận dụng API Tìm nạp trong nền để thử lại một yêu cầu xoá trạng thái trên máy chủ khi người dùng có kết nối mạng sau đó.

Cách giải phóng bộ nhớ

Trên phản hồi cho trang xác nhận trạng thái đã đăng xuất, hãy chú ý dọn dẹp dữ liệu nhạy cảm khỏi các kho dữ liệu khác nhau:

  • sessionStorage: Mặc dù trạng thái này bị xoá khi người dùng kết thúc phiên truy cập trên trang web của bạn, nhưng hãy cân nhắc việc chủ động xoá dữ liệu nhạy cảm khi người dùng đăng xuất, phòng trường hợp họ quên đóng tất cả các thẻ đã mở trên trang web của bạn.

    // Remove sensitive data from sessionStorage
    sessionStorage.removeItem('sensitiveSessionData1');
    // ...
    
    // Or if everything in sessionStorage is sensitive, clear it all
    sessionStorage.clear();
    
  • Các API localStorage, indexedDB, Cache/Service Worker: Khi người dùng đăng xuất, hãy xoá mọi dữ liệu nhạy cảm mà bạn có thể đã lưu trữ bằng những API này, vì những dữ liệu đó sẽ vẫn tồn tại qua nhiều phiên.

    // Remove sensitive data from localStorage:
    localStorage.removeItem('sensitiveData1');
    // ...
    
    // Or if everything in localStorage is sensitive, clear it all:
    localStorage.clear();
    
    // Delete sensitive object stores in indexedDB:
    const name = 'exampleDB';
    const version = 1;
    const request = indexedDB.open(name, version);
    
    request.onsuccess = (event) => {
      const db = request.result;
      db.deleteObjectStore('sensitiveStore1');
      db.deleteObjectStore('sensitiveStore2');
    
      // ...
    
      db.close();
    }
    
    // Delete sensitive resources stored via the Cache API:
    caches.open('cacheV1').then((cache) => {
      await cache.delete("/personal/profile.png");
    
      // ...
    }
    
    // Or better yet, clear a cache bucket that contains sensitive resources:
    caches.delete('personalizedV1');
    

Cách dọn dẹp bộ nhớ đệm

  • Bộ nhớ đệm HTTP: Miễn là bạn thiết lập Cache-control: no-store trên các tài nguyên có dữ liệu nhạy cảm, bộ nhớ đệm HTTP sẽ không giữ lại các nội dung nhạy cảm.
  • Bộ nhớ đệm cho thao tác tiến/lùi: Tương tự, nếu bạn làm theo các đề xuất về Cache-control: no-store và cách xoá cookie nhạy cảm (ví dụ: cookie bảo mật chỉ dùng giao thức HTTPS có liên quan đến quá trình xác thực) khi người dùng đăng xuất, thì bạn không cần lo lắng về việc dữ liệu nhạy cảm bị giữ lại trong bộ nhớ đệm cho thao tác tiến/lùi. Trên thực tế, tính năng bộ nhớ đệm cho thao tác tiến/lùi sẽ loại bỏ các trang có cùng nguồn gốc được phân phát kèm theo tiêu đề HTTP Cache-control: no-store nếu quan sát thấy một hoặc nhiều tín hiệu sau:
    • Một hoặc nhiều cookie chỉ an toàn chỉ dùng giao thức HTTPS đã bị sửa đổi hoặc xoá.
    • Một hoặc nhiều phản hồi cho lệnh gọi XHR/fetch (do trang cung cấp) có chứa tiêu đề HTTP Cache-control: no-store.

Trải nghiệm người dùng nhất quán trên các thẻ

Người dùng có thể đã mở nhiều thẻ trên trang web của bạn trước khi quyết định đăng xuất. Sau đó, trẻ có thể đã quên các thẻ khác hoặc thậm chí là các cửa sổ trình duyệt khác. Tốt nhất là bạn nên tránh dựa vào người dùng để đóng tất cả các thẻ và cửa sổ có liên quan. Thay vào đó, hãy chủ động thể hiện tình huống bằng cách đảm bảo rằng trạng thái đăng nhập của người dùng là nhất quán trên các thẻ.

Cách thực hiện

Để đạt được trạng thái đăng nhập nhất quán trên các thẻ, hãy cân nhắc sử dụng kết hợp sự kiện pageshow/pagehide và API kênh phát sóng.

  • Sự kiện pageshow: Sau khi pageshow tiếp tục xảy ra, hãy kiểm tra trạng thái đăng nhập của người dùng và xoá dữ liệu nhạy cảm (hoặc thậm chí là toàn bộ trang) nếu người dùng không còn đăng nhập nữa. Xin lưu ý rằng sự kiện pageshow sẽ kích hoạt trước khi trang hiển thị lần đầu tiên sau khi được khôi phục từ thành phần điều hướng tiến/lùi. Điều này đảm bảo rằng việc kiểm tra trạng thái đăng nhập sẽ cho phép bạn đặt lại trang về trạng thái không nhạy cảm.

    window.addEventListener('pageshow', (event) => {
      if (event.persisted && !document.cookie.match(/my-cookie)) {
        // The user has logged out.
        // Force a reload, or otherwise clear sensitive information right away.
        body.innerHTML = '';
        location.reload();
      }
    });
    
  • API Kênh truyền hình: Sử dụng API này để thông báo về việc thay đổi trạng thái đăng nhập giữa các thẻ và cửa sổ. Nếu người dùng đã đăng xuất, hãy xoá mọi dữ liệu nhạy cảm hoặc chuyển hướng đến trang đăng xuất trên tất cả các thẻ và cửa sổ có dữ liệu nhạy cảm.

    // Upon logout, broadcast new login state so that other tabs can clean up too:
    const bc = new BroadcastChannel('login-state');
    bc.postMessage('logged out');
    
    // [...]
    const bc = new BroadcastChannel('login-state');
    bc.onMessage = (msgevt) => {
      if (msgevt.data === 'logged out') {
        // Clean up, reload or navigate to the sign-out page.
        // ...
      }
    }
    

Kết luận

Bằng cách làm theo hướng dẫn trong tài liệu này, bạn có thể thiết kế một trải nghiệm đăng xuất chất lượng cao cho người dùng, giúp ngăn chặn người dùng đăng xuất ngoài ý muốn và bảo vệ thông tin cá nhân của người dùng.