ما الذي يجعل تجربة تسجيل الخروج جيدة؟

Kenji Baheux
Kenji Baheux

عندما يسجِّل المستخدم خروجه من موقع إلكتروني، يعني ذلك أنّه يبلّغ عن رغبته في الاستفادة بشكل كامل من تجربة مخصّصة للمستخدم. وبالتالي، من المهم الالتزام بأكبر قدر ممكن بالنموذج العقلي للمستخدم. على سبيل المثال، يجب أن تراعي تجربة تسجيل الخروج المناسبة أيضًا أي علامات تبويب ربما فتحها المستخدم قبل أن يقرر تسجيل الخروج.

يمكن تلخيص مفتاح تجربة تسجيل الخروج الرائعة في الاتساق عبر الجوانب المرئية والحالة لتجربة المستخدم. يقدّم هذا الدليل نصائح ملموسة حول ما يجب الانتباه إليه وكيفية توفير تجربة جيدة لتسجيل الخروج.

اعتبارات رئيسية

عند تنفيذ وظيفة تسجيل الخروج على موقعك الإلكتروني، عليك مراعاة الجوانب التالية لضمان توفير عملية تسجيل خروج سلسة وآمنة وسهلة الاستخدام:

  • تجربة مستخدم واضحة ومتسقة لتسجيل الخروج: يجب توفير رابط أو زر لتسجيل الخروج واضح وثابت يمكن العثور عليه بسهولة ويمكن الوصول إليه من خلال الموقع الإلكتروني. تجنَّب استخدام تصنيفات غامضة أو إخفاء وظيفة تسجيل الخروج في القوائم الغامضة أو الصفحات الفرعية أو المواقع الجغرافية الأخرى غير الواضحة.
  • طلب التأكيد: يمكنك تنفيذ طلب تأكيد قبل إنهاء عملية تسجيل الخروج. يمكن أن يساعد ذلك في منع تسجيل خروج المستخدمين عن طريق الخطأ، كما يسمح لهم بإعادة النظر في حال كان عليهم فعلاً تسجيل الخروج، على سبيل المثال، في حال قفل أجهزتهم بعناية باستخدام كلمة مرور قوية أو آلية مصادقة أخرى.
  • التعامل مع علامات تبويب متعدّدة: إذا فتح أحد المستخدمين عدة صفحات من الموقع الإلكتروني نفسه ضمن علامات تبويب مختلفة، احرص على أن يؤدي تسجيل الخروج من علامة تبويب واحدة إلى تعديل جميع علامات التبويب المفتوحة الأخرى من هذا الموقع الإلكتروني أيضًا.
  • إعادة التوجيه إلى صفحة مقصودة آمنة: عند تسجيل الخروج بنجاح، أعِد توجيه المستخدِم إلى صفحة مقصودة آمنة تشير بوضوح إلى أنّه لم يعُد مسجّلاً الدخول. تجنب إعادة توجيه المستخدمين إلى صفحات تحتوي على أي معلومات مخصصة. وبالمثل، يمكنك التأكّد من أنّ علامات التبويب الأخرى لم تعد تعرض حالة تسجيل الدخول أيضًا. وعليك أيضًا الحرص على عدم إنشاء إعادة توجيه مفتوحة يمكن للمهاجمين استغلالها.
  • تنظيف الجلسة: بعد تسجيل خروج المستخدم، أزِل نهائيًا أي بيانات حساسة لجلسة المستخدم أو ملفات تعريف الارتباط أو ملفات مؤقتة مرتبطة بجلسة المستخدم. ويؤدي ذلك إلى منع الوصول غير المصرَّح به إلى معلومات المستخدم أو نشاط الحساب، كما سيمنع المتصفِّح أيضًا من استعادة الصفحات التي تحتوي على معلومات حسّاسة من ذاكرات التخزين المؤقت المختلفة، ولا سيما ميزة التخزين المؤقت للصفحات.
  • معالجة الأخطاء وتقديم الملاحظات: يجب تقديم رسائل خطأ أو ملاحظات واضحة للمستخدمين في حال حدوث أي مشاكل عند تسجيل الخروج. إبلاغهم بأي مخاطر أمنية محتملة أو تسرُّب للبيانات في حال تعذُّر عملية تسجيل الخروج.
  • اعتبارات إمكانية الوصول: تأكَّد من إمكانية وصول المستخدمين الذين يعانون من عجز إلى آلية تسجيل الخروج، بما في ذلك أولئك الذين يستخدمون تقنيات مساعدة، مثل برامج قراءة الشاشة أو التنقّل باستخدام لوحة المفاتيح.
  • التوافق عبر المتصفحات: اختبر وظيفة تسجيل الخروج عبر مختلف المتصفحات والأجهزة للتأكد من أنها تعمل بشكل متسق وموثوق به.
  • المراقبة والتحديثات المستمرة: راقِب عملية تسجيل الخروج بانتظام بحثًا عن أي ثغرات أمنية أو ثغرات أمنية محتملة. نفِّذ التحديثات والتصحيحات في الوقت المناسب لمعالجة أي مشاكل يتم تحديدها.
  • توحيد الهوية: إذا سجَّل المستخدم الدخول باستخدام هوية موحّدة، تأكَّد مما إذا كان تسجيل الخروج من موفِّر الهوية أيضًا متاحًا ومطلوبًا. بالإضافة إلى ذلك، إذا كان موفِّر الهوية يتيح تسجيل الدخول تلقائيًا، لا تنسَ منعه.

الإجراءات المسموح بها

  • وفي حال إيقاف ملف تعريف ارتباط على الخادم كجزء من عملية تسجيل الخروج (أو مسارات أخرى لإبطال الوصول)، تأكَّد من حذف ملف تعريف الارتباط على جهاز المستخدم أيضًا.
  • احذف أي بيانات حسّاسة قد خزّنتها على جهاز المستخدم، مثل ملفات تعريف الارتباط وlocalStorage وsessionStorage وindexedDB وCacheStorage وأي مخازن بيانات محلية أخرى.
  • تأكَّد من عرض أي موارد تحتوي على بيانات حسّاسة، لا سيما مستندات HTML، باستخدام عنوان HTTP Cache-control: no-store كي لا يخزِّن المتصفّح هذه الموارد في مساحة تخزين دائمة (على سبيل المثال، على القرص). وبالمثل، فإنّ طلبات XHR/fetch التي تعرض بيانات حسّاسة يجب أيضًا ضبط عنوان HTTP يتضمّن Cache-Control: no-store لمنع أي تخزين مؤقت.
  • تأكَّد من أنّ أي علامات تبويب مفتوحة على جهاز المستخدم محدَّثة مع عمليات إبطال الوصول من جهة الخادم.

تنظيف البيانات الحساسة عند تسجيل الخروج

عند تسجيل الخروج، ننصحك بمحو البيانات المؤقتة والبيانات الحسّاسة المخزّنة محليًا. يتم التركيز على البيانات الحساسة من حقيقة أن مسح كل شيء سيؤدي إلى تجربة مستخدم أسوأ بكثير لأن هذا المستخدم قد يعود بشكل جيد للغاية. على سبيل المثال، إذا كنت تريد محو جميع البيانات المخزَّنة محليًا، سيحتاج المستخدمون بعد ذلك إلى إعادة الإقرار باستلام طلبات الموافقة على ملفات تعريف الارتباط، وإجراء عمليات أخرى كما لو أنهم لم يزوروا موقعك الإلكتروني من الأساس.

كيفية حذف ملفات تعريف الارتباط

في استجابة الصفحة التي تؤكد حالة تسجيل الخروج، أرفق عناوين HTTP التي تتضمن Set-Cookie لمحو كل ملف تعريف ارتباط مرتبط ببيانات حساسة أو يحتوي عليها. اضبط القيمة expires على تاريخ في الماضي البعيد، واضبط قيمة ملف تعريف الارتباط على سلسلة فارغة، وهذا إجراء جيد.

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
...

سيناريو عدم الاتصال بالإنترنت

على الرغم من أن الطريقة الموضحة أعلاه كافية لحالات الاستخدام العامة، إلا أنها لا تعمل إذا كان المستخدم يعمل بلا اتصال بالإنترنت. قد تحتاج إلى طلب ملفَّي تعريف ارتباط لتتبّع حالة تسجيل الدخول، أحدهما ملفّ تعريف ارتباط آمن HTTPS فقط، وملفّ تعريف ارتباط عادي يمكن الوصول إليه من خلال JavaScript. إذا حاول المستخدم تسجيل الخروج بلا اتصال بالإنترنت، يمكنك محو ملف تعريف ارتباط JavaScript ومتابعة عمليات التنظيف الأخرى إن أمكن. إذا كان لديك مشغّل خدمات، قد تحتاج أيضًا إلى الاستفادة من واجهة برمجة تطبيقات استرجاع البيانات في الخلفية لإعادة محاولة طلب محو حالة على الخادم عندما يكون المستخدم متصلاً بالإنترنت لاحقًا.

كيفية إخلاء مساحة التخزين

في الردّ الخاص بالصفحة التي تؤكد حالة تسجيل الخروج، احرِص على حذف البيانات الحسّاسة من مخازن البيانات المختلفة:

  • sessionStorage: على الرغم من إزالة هذه العلامة عندما ينهي المستخدم الجلسة مع موقعك الإلكتروني، ننصحك بتنظيف البيانات الحسّاسة بشكل استباقي عندما يسجّل المستخدم خروجه، وذلك في حال نسيَ إغلاق جميع علامات التبويب المفتوحة على موقعك الإلكتروني.

    // Remove sensitive data from sessionStorage
    sessionStorage
    .removeItem('sensitiveSessionData1');
    // ...

    // Or if everything in sessionStorage is sensitive, clear it all
    sessionStorage
    .clear();
  • واجهات برمجة تطبيقات localStorage وindexedDB وذاكرة التخزين المؤقت/مشغّل الخدمات: عندما يسجِّل المستخدم خروجه، يجب محو أي بيانات حسّاسة خزّنَتها باستخدام واجهات برمجة التطبيقات هذه، لأنّ هذه البيانات قد تظل سارية على مستوى الجلسات.

    // 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');

كيفية حذف ذاكرات التخزين المؤقت

  • ذاكرة التخزين المؤقت لـ HTTP: طالما يتم ضبط Cache-control: no-store على موارد تحتوي على بيانات حساسة، لن تحتفظ ذاكرة التخزين المؤقت HTTP بأي معلومات حساسة.
  • ميزة "التخزين المؤقت للصفحات": بالمثل، إذا اتّبعت الاقتراحات بشأن "Cache-control: no-store" وامحُت ملفات تعريف الارتباط الحساسة (على سبيل المثال، ملفات تعريف الارتباط الآمنة التي تستخدم HTTPS فقط والمرتبطة بالمصادقة) عندما يسجّل المستخدمون خروجهم، لا داعي للقلق بشأن الاحتفاظ بالبيانات الحسّاسة في ميزة "التخزين المؤقت للصفحات". وبالفعل، ستزيل ميزة "التخزين المؤقت للصفحات" صفحات المصدر نفسه التي يتم عرضها باستخدام عنوان HTTP يتضمّن العنصر Cache-control: no-store، وذلك في حال رصد إشارة واحدة أو أكثر من الإشارات التالية:
    • تم تعديل أو حذف ملف تعريف ارتباط واحد أو أكثر آمن يستخدم HTTPS فقط.
    • يتضمّن ردّ واحد أو أكثر لطلبات XHRs/fetch الصادرة عن الصفحة عنوان HTTP يتضمّن Cache-control: no-store.

تجربة مستخدم متسقة على مستوى علامات التبويب

من المحتمل أن يكون المستخدمون قد فتحوا العديد من علامات التبويب لموقعك الإلكتروني قبل أن يقرّروا تسجيل الخروج منه. وعندئذٍ، قد يكونون قد نسوا علامات التبويب الأخرى، أو حتى نوافذ المتصفح الأخرى. من الأفضل تجنب الاعتماد على المستخدمين لإغلاق جميع علامات التبويب والنوافذ ذات الصلة. بدلاً من ذلك، يمكنك اتخاذ موقفًا استباقيًا من خلال التأكد من اتساق حالة تسجيل دخول المستخدم عبر علامات التبويب.

طريقة التنفيذ

لتسجيل الدخول بشكل منتظم في مختلف علامات التبويب، ننصحك باستخدام مجموعة من أحداث pageshow من pagehide وواجهة برمجة التطبيقات Broadcast Channel API.

  • حدث pageshow: عند استمرار pageshow، تحقَّق من حالة تسجيل دخول المستخدم وامحُ البيانات الحسّاسة، أو حتى من الصفحة بأكملها، وذلك في حال لم يعُد المستخدم مسجّلاً الدخول. تجدر الإشارة إلى أنّه سيتم تشغيل حدث pageshow قبل عرض الصفحة لأول مرة عند استعادتها من خلال ميزة التنقّل باستخدام ميزة الانتقال للخلف/الأمام، ما يضمن لك أن تتيح لك عملية التحقّق من حالة تسجيل الدخول إعادة ضبط الصفحة إلى حالة غير حسّاسة.

    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();
     
    }
    });
  • Broadcast Channel API: يمكنك استخدام واجهة برمجة التطبيقات هذه للإبلاغ عن تغييرات حالة تسجيل الدخول على مستوى علامات التبويب والنوافذ. وفي حال تسجيل خروج المستخدم، عليك محو جميع البيانات الحسّاسة أو إعادة التوجيه إلى صفحة تسجيل الخروج في جميع علامات التبويب والنوافذ التي تحتوي على بيانات حسّاسة.

    // 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.
       
    // ...
     
    }
    }

الخاتمة

من خلال اتّباع الإرشادات الواردة في هذا المستند، ستتمكّن من تقديم تجربة رائعة للمستخدمين عند تسجيل الخروج، وهي تمنع عمليات تسجيل الخروج غير المقصودة، وتحمي معلوماتهم الشخصية.