أفضل الممارسات لنموذج كلمة المرور لمرة واحدة عبر الرسائل القصيرة SMS

من الشائع أن تطلب من المستخدم تقديم كلمة مرور صالحة لمرة واحدة (OTP) لتأكيد هويته من خلال إرسال رسالة قصيرة SMS. تشمل بعض حالات استخدام كلمات المرور الصالحة لمرة واحدة عبر الرسائل القصيرة ما يلي:

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

يُرجى مواصلة القراءة للاطّلاع على أفضل الممارسات المتعلّقة بإنشاء نماذج كلمات المرور الصالحة لمرة واحدة (OTP) عبر الرسائل القصيرة لحالات الاستخدام هذه.

قائمة التحقق

لتقديم أفضل تجربة للمستخدم من خلال كلمة المرور الصالحة لمرة واحدة عبر الرسائل القصيرة، اتّبِع الخطوات التالية:

  • استخدِم العنصر <input> مع:
    • type="text"
    • inputmode="numeric"
    • autocomplete="one-time-code"
  • استخدِم @BOUND_DOMAIN #OTP_CODE كآخر سطر في رسالة SMS التي تتضمّن كلمة المرور الصالحة لمرة واحدة.
  • استخدِم WebOTP API.

استخدام العنصر <input>

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

<form action="/verify-otp" method="POST">
  <input type="text"
      inputmode="numeric"
      autocomplete="one-time-code"
      pattern="\d{6}"
      required>
</form>

في ما يلي بعض الأفكار لضمان استفادة حقل الإدخال من وظائف المتصفّح على أفضل نحو.

type="text"

بما أنّ كلمات المرور الصالحة لمرة واحدة تتكوّن عادةً من خمسة أو ستة أرقام، قد يبدو استخدام type="number" لحقل الإدخال بديهيًا لأنّه يغيّر لوحة المفاتيح على الأجهزة الجوّالة إلى أرقام فقط. لا يُنصح بذلك لأنّ المتصفّح يتوقّع أن يكون حقل الإدخال رقمًا قابلاً للعدّ وليس تسلسلاً من أرقام متعددة، ما قد يؤدي إلى سلوك غير متوقّع. يؤدي استخدام type="number" إلى عرض زرَّين، أحدهما متّجه للأعلى والآخر للأسفل، بجانب حقل الإدخال. ويؤدي الضغط على هذين الزرَّين إلى زيادة الرقم أو إنقاصه وقد يؤدي إلى إزالة الأصفار السابقة.

يمكنك استخدام type="text" كبديل. لن يؤدي ذلك إلى تحويل لوحة المفاتيح على الأجهزة الجوّالة إلى أرقام فقط، ولكن لا بأس بذلك لأنّ النصيحة التالية لاستخدام inputmode="numeric" تؤدي هذه المهمة.

inputmode="numeric"

استخدِم inputmode="numeric" لتغيير لوحة المفاتيح على الجهاز الجوّال إلى الأرقام فقط.

تستخدم بعض المواقع الإلكترونية type="tel" لحقول إدخال كلمة المرور الصالحة لمرة واحدة (OTP) لأنّها أيضًا تحوّل لوحة مفاتيح الأجهزة الجوّالة إلى أرقام فقط (بما في ذلك * و#) عند التركيز عليها. تم استخدام هذه الطريقة في الماضي عندما لم يكن inputmode="numeric" متاحًا على نطاق واسع. بما أنّ Firefox بدأ يتيح استخدام inputmode="numeric"، فلا داعي لاستخدام الاختراق type="tel" غير الصحيح دلاليًا.

autocomplete="one-time-code"

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

باستخدام autocomplete="one-time-code"، عندما يتلقّى المستخدم رسالة SMS أثناء فتح نموذج، سيحلّل نظام التشغيل كلمة المرور الصالحة لمرة واحدة (OTP) في رسالة SMS بشكل إرشادي وستقترح لوحة المفاتيح كلمة المرور الصالحة لمرة واحدة (OTP) على المستخدم لإدخالها. لا تعمل هذه السمة إلا على Safari 12 والإصدارات الأحدث على iOS وiPadOS وmacOS، ولكننا ننصح بشدة باستخدامها لأنّها طريقة أفضل لتحسين تجربة استخدام كلمة المرور لمرة واحدة (OTP) عبر الرسائل القصيرة على هذه الأنظمة الأساسية.

ذكرى لـ "autocomplete="one-time-code"" من قلب الحدث

يؤدي استخدام autocomplete="one-time-code" إلى تحسين تجربة المستخدم، ولكن يمكنك اتخاذ المزيد من الإجراءات من خلال التأكّد من أنّ رسالة SMS تتوافق مع تنسيق الرسائل المرتبطة بالمصدر.

السمات الاختيارية

تشمل السمات الاختيارية ما يلي:

  • pattern تحدّد التنسيق الذي يجب أن تتطابق معه كلمة المرور الصالحة لمرة واحدة التي تم إدخالها. استخدِم التعبيرات العادية لتحديد النمط المطابق. على سبيل المثال، يفرض \d{6} أن تكون كلمة المرور الصالحة لمرة واحدة (OTP) عبارة عن سلسلة من ستة أرقام. يمكنك الاطّلاع على مقالة استخدام JavaScript لإجراء عمليات تحقّق أكثر تعقيدًا في الوقت الفعلي لمزيد من المعلومات حول pattern.
  • تشير العلامة required إلى أنّه يجب على المستخدم ملء الحقل.

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

تنسيق نص الرسالة القصيرة SMS

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

في الأساس، تكون قاعدة التنسيق على النحو التالي: إنهاء رسالة SMS بنطاق المستلِم مسبوقًا بـ @، وكلمة المرور الصالحة لمرة واحدة مسبوقة بـ #.

على سبيل المثال:

Your OTP is 123456

@web-otp.example.com #123456

يؤدي التنسيق العادي لرسائل OTP إلى تسهيل عملية الاستخراج وزيادة موثوقيتها. يؤدي ربط رموز OTP بالمواقع الإلكترونية إلى زيادة صعوبة خداع المستخدمين لتقديم رمز إلى المواقع الإلكترونية الضارة.

قواعد التنسيق الدقيقة

القواعد الدقيقة هي:

  • تبدأ الرسالة بنص يمكن لشخص عادي قراءته (اختياري) يحتوي على سلسلة أبجدية رقمية تتألف من أربعة إلى عشرة أحرف مع رقم واحد على الأقل، مع ترك السطر الأخير لعنوان URL وكلمة المرور الصالحة لمرة واحدة.
  • يجب أن يسبق @ جزء النطاق من عنوان URL للموقع الإلكتروني الذي استدعى واجهة برمجة التطبيقات.
  • يجب أن يحتوي عنوان URL على #، متبوعًا بكلمة المرور الصالحة لمرة واحدة. يجب ألا يزيد عدد الأحرف عن 140 حرفًا.

يوفّر استخدام هذا التنسيق ميزتَين:

  • سيتم ربط كلمة المرور الصالحة لمرة واحدة بالنطاق. إذا كان المستخدم على نطاقات أخرى غير النطاق المحدّد في رسالة SMS، لن يظهر اقتراح كلمة المرور الصالحة لمرة واحدة. ويحدّ ذلك أيضًا من خطر هجمات التصيّد الاحتيالي وعمليات الاستيلاء المحتملة على الحسابات.
  • سيتمكّن المتصفّح الآن من استخراج كلمة المرور الصالحة لمرة واحدة (OTP) بشكل موثوق بدون الاعتماد على الأساليب الإرشادية الغامضة وغير الموثوقة.

عندما يستخدم موقع إلكتروني autocomplete="one-time-code"، سيقترح متصفّح Safari على نظام التشغيل iOS 14 أو الإصدارات الأحدث كلمة المرور الصالحة لمرة واحدة (OTP) باتّباع هذه القواعد.

يستفيد من تنسيق الرسائل القصيرة هذا أيضًا المتصفّحات الأخرى غير Safari. تتوافق أيضًا متصفّحات Chrome وOpera وVivaldi على أجهزة Android مع قاعدة الرموز لمرة واحدة المرتبطة بالمصدر من خلال واجهة برمجة التطبيقات WebOTP API، ولكن ليس من خلال autocomplete="one-time-code".

استخدام WebOTP API

تتيح WebOTP API الوصول إلى كلمة المرور الصالحة لمرة واحدة (OTP) التي يتم تلقّيها في رسالة قصيرة SMS. من خلال استدعاء navigator.credentials.get() باستخدام النوع otp (OTPCredential) حيث يتضمّن transport sms، سينتظر الموقع الإلكتروني رسالة SMS تتوافق مع الرموز التي تُستخدَم لمرة واحدة والمرتبطة بالمصدر ليتم تسليمها ومنح المستخدم إذن الوصول إليها. بعد تمرير كلمة المرور الصالحة لمرة واحدة إلى JavaScript، يمكن للموقع الإلكتروني استخدامها في نموذج أو إرسالها مباشرةً إلى الخادم.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
واجهة WebOTP API قيد العمل

تعرَّف على كيفية استخدام WebOTP API بالتفصيل في مقالة التحقّق من أرقام الهواتف على الويب باستخدام WebOTP API أو انسخ المقتطف التالي والصقه. احرص على ضبط السمتَين action وmethod في <form>.

// Feature detection
if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    // Cancel the WebOTP API if the form is submitted manually.
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        // Cancel the WebOTP API.
        ac.abort();
      });
    }
    // Invoke the WebOTP API
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      // Automatically submit the form when an OTP is obtained.
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}