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

Kenji Baheux
Kenji Baheux

الخروج

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

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

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

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

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

DOs

  • إذا أبطلت ملف تعريف ارتباط على الخادم كجزء من عملية تسجيل الخروج (أو عمليات أخرى لإبطال إذن الوصول)، احرص على حذف ملف تعريف الارتباط على جهاز المستخدم أيضًا.
  • امحُ أي بيانات حسّاسة قد تكون قد حفظتها على جهاز المستخدم، مثل ملفات تعريف الارتباط و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 ومواصلة عمليات التنظيف الأخرى إن أمكن. إذا كان لديك عامل خدمة، يمكنك أيضًا الاستفادة من Background Fetch API لإعادة محاولة طلب محو الحالة على الخادم عندما يكون المستخدم متصلاً بالإنترنت لاحقًا.

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

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

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

    // Remove sensitive data from sessionStorage
    sessionStorage.removeItem('sensitiveSessionData1');
    // ...
    
    // Or if everything in sessionStorage is sensitive, clear it all
    sessionStorage.clear();
    
  • واجهات برمجة التطبيقات localStorage وindexedDB وCache/Service Worker: عند تسجيل خروج المستخدم، عليك تنظيف أي بيانات حسّاسة قد تكون قد حفظتها باستخدام واجهات برمجة التطبيقات هذه، لأنّ هذه البيانات ستظل محفوظة على مدار الجلسات.

    // 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 فقط أو حذفه.
    • تضمّن استجابة واحدة أو أكثر لطلبات XHR/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.
        // ...
      }
    }
    

الخاتمة

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