إثبات ملكية أرقام الهواتف على الويب باستخدام WebOTP API

مساعدة المستخدمين بشأن كلمات المرور لمرة واحدة (OTP) المرسَلة عبر الرسائل القصيرة SMS

إيجي كيتامورا
إيجي كيتامورا

ما هي WebOTP API؟

في هذه الأيام، يمتلك معظم الأشخاص في العالم جهازًا جوّالاً ويستخدم المطوّرون عادةً أرقام الهواتف كمعرّف لمستخدمي خدماتهم.

هناك عدة طرق لإثبات ملكية أرقام الهواتف، ولكن الأكثر شيوعًا هو كلمة المرور التي تُستخدم مرة واحدة (OTP) ويتم إنشاؤها عشوائيًا. يوضح إرسال هذا الرمز مرة أخرى إلى خادم المطور التحكم في رقم الهاتف.

وقد سبق أن تمّ نشر هذه الفكرة في العديد من السيناريوهات لتحقيق ما يلي:

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

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

تسمح WebOTP API لتطبيقك بتلقّي رسائل منسّقة بشكل خاص مرتبطة بنطاق تطبيقك. وبهذا، يمكنك الحصول آليًا على كلمة مرور لمرة واحدة (OTP) من رسالة SMS والتحقق من رقم هاتف المستخدم بسهولة أكبر.

أمثلة واقعية

لنفترض أن أحد المستخدمين يريد إثبات ملكية رقم هاتفه باستخدام موقع إلكتروني. يرسل الموقع الإلكتروني رسالة نصية إلى المستخدم عبر رسالة قصيرة SMS ويُدخل المستخدم كلمة المرور لمرة واحدة (OTP) من الرسالة لإثبات ملكية رقم الهاتف.

باستخدام WebOTP API، تكون هذه الخطوات سهلة بنقرة واحدة على المستخدم، كما هو موضّح في الفيديو. عند وصول الرسالة النصية، تنبثق بطاقة سفلية وتطالب المستخدم بالتحقق من رقم هاتفه. بعد النقر على زر إثبات الملكية في البطاقة السفلية، يلصق المتصفّح كلمة المرور لمرة واحدة (OTP) في النموذج ويتم إرسال النموذج بدون أن يحتاج المستخدم إلى الضغط على متابعة.

العملية بأكملها مخططة في الصورة أدناه.

مخطّط واجهة برمجة تطبيقات WebOTP API

جرِّب الإصدار التجريبي بنفسك. إنه لا يطلب رقم هاتفك أو يرسل رسالة قصيرة SMS إلى جهازك، ولكن يمكنك إرسال رقم من جهاز آخر عن طريق نسخ النص المعروض في العرض التوضيحي. وينجح ذلك لأنّه لا يهمّ هوية المرسِل عند استخدام WebOTP API.

  1. انتقِل إلى https://web-otp.glitch.me في الإصدار 84 من Chrome أو لاحقًا على جهاز Android.
  2. أرسل الرسالة النصية القصيرة التالية إلى هاتفك من هاتف آخر.
Your OTP is: 123456.

@web-otp.glitch.me #12345

هل تلقيت رسالة SMS ورأيت رسالة تطلب منك إدخال الرمز في منطقة الإدخال؟ هذه هي الطريقة التي تعمل بها واجهة برمجة التطبيقات WebOTP API للمستخدمين.

يتكوّن استخدام واجهة برمجة التطبيقات WebOTP API من ثلاثة أجزاء:

  • علامة <input> تم التعليق عليها بشكل صحيح
  • JavaScript في تطبيق الويب
  • نص الرسالة المنسقة التي تم إرسالها عبر الرسائل القصيرة SMS.

سأغطي علامة <input> أولاً.

إضافة تعليق توضيحي على علامة <input>

تعمل أداة WebOTP نفسها بدون أي تعليقات توضيحية بتنسيق HTML، ولكن للحفاظ على توافقها مع جميع المتصفّحات، ننصحك بشدّة بإضافة autocomplete="one-time-code" إلى العلامة <input> حيث تتوقع أن يُدخل المستخدم كلمة مرور صالحة لمرة واحدة (OTP).

يتيح ذلك للإصدار 14 من Safari أو الإصدارات الأحدث أن يقترح على المستخدم الملء التلقائي للحقل <input> باستخدام كلمة OTP عندما يتلقّى رسالة قصيرة SMS بالتنسيق الموضّح في تنسيق رسالة SMS على الرغم من عدم إتاحة WebOTP.

HTML

<form>
  <input autocomplete="one-time-code" required/>
  <input type="submit">
</form>

استخدام WebOTP API

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

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}

اكتشاف الميزات

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

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    …
    const form = input.closest('form');
    …
  });
}

معالجة كلمة المرور لمرة واحدة (OTP)

واجهة برمجة تطبيقات WebOTP API نفسها بسيطة بما فيه الكفاية. استخدِم navigator.credentials.get() للحصول على كلمة المرور لمرة واحدة. تضيف WebOTP خيار otp جديدًا إلى هذه الطريقة. ويحتوي على خاصية واحدة فقط: transport، التي يجب أن تكون قيمتها صفيفًا يتضمن السلسلة 'sms'.

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
    …

يؤدي ذلك إلى تشغيل تدفق أذونات المتصفح عند وصول رسالة قصيرة SMS. في حال منح الإذن، يتم حلّ الوعد المعروض باستخدام كائن OTPCredential.

محتوى العنصر الذي تم الحصول عليه OTPCredential

{
  code: "123456" // Obtained OTP
  type: "otp"  // `type` is always "otp"
}

بعد ذلك، أدخِل قيمة كلمة المرور لمرة واحدة (OTP) إلى الحقل <input>. سيؤدي إرسال النموذج مباشرة إلى إزالة الخطوة التي تتطلب من المستخدم النقر فوق الزر.

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.error(err);
    });
    …

إلغاء الرسالة

إذا أدخل المستخدم كلمة المرور لمرة واحدة (OTP) يدويًا وأرسل النموذج، يمكنك إلغاء طلب get() باستخدام مثيل AbortController في كائن options.

JavaScript

    …
    const ac = new AbortController();
    …
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    …
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
    …

تنسيق رسالة SMS

يجب أن تبدو واجهة برمجة التطبيقات نفسها بسيطة بما فيه الكفاية، ولكن هناك بعض الأشياء التي يجب عليك معرفتها قبل استخدامها. يجب إرسال الرسالة بعد استدعاء navigator.credentials.get()، ويجب استلامها على الجهاز الذي تم استدعاء get() منه. أخيرًا، يجب أن تتقيد الرسالة بالتنسيق التالي:

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

مثلاً:

Your OTP is: 123456.

@www.example.com #123456

إليك أمثلة خاطئة:

مثال على نص رسالة قصيرة SMS مكتوبة بشكلٍ غير صحيح سبب عدم نجاح هذا الإجراء
Here is your code for @example.com #123456 يُتوقع أن يكون @ هو الحرف الأول من السطر الأخير.
Your code for @example.com is #123456 يُتوقع أن يكون @ هو الحرف الأول من السطر الأخير.
Your verification code is 123456

@example.com\t#123456
من المتوقع أن تتراوح المسافة بين @host و#code.
Your verification code is 123456

@example.com  #123456
من المتوقع أن تتراوح المسافة بين @host و#code.
Your verification code is 123456

@ftp://example.com #123456
لا يمكن تضمين مخطط عنوان URL.
Your verification code is 123456

@https://example.com #123456
لا يمكن تضمين مخطط عنوان URL.
Your verification code is 123456

@example.com:8080 #123456
تعذَّر تضمين المنفذ.
Your verification code is 123456

@example.com/foobar #123456
يتعذّر تضمين المسار.
Your verification code is 123456

@example .com #123456
لا توجد مسافة بيضاء في النطاق.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
ليس هناك أحرف محظورة في النطاق.
@example.com #123456

Mambo Jumbo
من المتوقّع أن يكون @host و#code آخر سطر.
@example.com #123456

App hash #oudf08lkjsdf834
من المتوقّع أن يكون @host و#code آخر سطر.
Your verification code is 123456

@example.com 123456
# مفقود.
Your verification code is 123456

example.com #123456
@ مفقود.
Hi mom, did you receive my last text ما مِن @ و#.

إصدارات تجريبية

جرِّب رسائل مختلفة باستخدام العرض التوضيحي: https://web-otp.glitch.me

يمكنك أيضًا إجراء شوكة وإنشاء نسختك: https://glitch.com/edit/#!/web-otp.

استخدام WebOTP من إطار iframe متعدد المصادر

يُستخدم عادةً إدخال كلمة المرور لمرة واحدة (OTP) إلى إطار iframe متعدد المصادر لتأكيد الدفع، خاصةً مع نظام 3D Secure. توفّر واجهة WebOTP API التنسيق الشائع لإتاحة إطارات iframe المتعددة المصادر، وتعرض كلمات المرور لمرة واحدة (OTP) المرتبطة بأصول متداخلة. على سبيل المثال:

  • يزور أحد المستخدمين shop.example لشراء زوج من الأحذية باستخدام بطاقة ائتمان.
  • بعد إدخال رقم بطاقة الائتمان، يعرض مقدّم خدمات الدفع المتكامل نموذجًا من bank.example ضمن إطار iframe يطلب من المستخدم إثبات ملكية رقم هاتفه لإتمام الدفع بسرعة.
  • يرسل bank.example رسالة قصيرة SMS تحتوي على كلمة مرور لمرة واحدة إلى المستخدم ليتمكن من إدخالها لإثبات هويته.

لاستخدام WebOTP API من داخل إطار iframe متعدد المصادر، عليك تنفيذ شيئين:

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

يمكنك تجربة العرض التوضيحي على https://web-otp-iframe-demo.stackblitz.io.

إضافة تعليق توضيحي على المصادر المرتبطة بالرسالة النصية القصيرة

عند استدعاء WebOTP API من داخل iframe، يجب أن تتضمّن الرسالة النصية القصيرة SMS أصل الإطار العلوي مسبوقًا بـ @ متبوعًا بكلمة OTP المسبوقة بـ # وأصل iframe المسبوق بـ @ في السطر الأخير.

Your verification code is 123456

@shop.example #123456 @bank.exmple

إعداد سياسة الأذونات

لاستخدام WebOTP في إطار iframe متعدد المصادر، يجب أن تمنح أداة التضمين إمكانية الوصول إلى واجهة برمجة التطبيقات هذه عبر سياسة الأذونات لبيانات اعتماد otp لتجنُّب حدوث سلوك غير مقصود. بوجه عام، هناك طريقتان لتحقيق هذا الهدف:

عبر عنوان HTTP:

Permissions-Policy: otp-credentials=(self "https://bank.example")

عبر سمة iframe allow:

<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

اطّلِع على مزيد من الأمثلة حول كيفية تحديد سياسة أذونات .

استخدام WebOTP على أجهزة الكمبيوتر المكتبي

في Chrome، تتيح أداة WebOTP الاستماع إلى الرسائل القصيرة SMS المُستلَمة على أجهزة أخرى لمساعدة المستخدمين في إكمال عملية إثبات ملكية رقم الهاتف على جهاز كمبيوتر مكتبي.

واجهة برمجة تطبيقات WebOTP على أجهزة الكمبيوتر المكتبي.

وتتطلّب هذه الإمكانية من المستخدم تسجيل الدخول إلى حساب Google نفسه على كلٍّ من متصفِّح Chrome المتوافق مع أجهزة الكمبيوتر المكتبي وChrome لنظام التشغيل Android.

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

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

الأسئلة الشائعة

لا يظهر مربع الحوار بالرغم من إرسالي رسالة منسقة بشكل صحيح. ما المشكلة؟

هناك بعض التنبيهات عند اختبار واجهة برمجة التطبيقات:

  • إذا كان رقم هاتف المرسل مدرجًا في قائمة جهات الاتصال للمستلم، فلن يتم تشغيل واجهة برمجة التطبيقات هذه بسبب تصميم واجهة برمجة تطبيقات موافقة مستخدم الرسائل القصيرة SMS الأساسية.
  • في حال استخدام ملف شخصي للعمل على جهاز Android وكانت خدمة WebOTP لا تعمل، جرِّب تثبيت Chrome واستخدامه في ملفك الشخصي بدلاً من ذلك (أي الملف الشخصي نفسه الذي تتلقّى من خلاله الرسائل القصيرة SMS).

يمكنك التحقق مرة أخرى من التنسيق لمعرفة ما إذا كان تنسيق الرسالة القصيرة SMS صحيحًا أم لا.

هل تتوافق واجهة برمجة التطبيقات هذه بين المتصفحات المختلفة؟

اتفق Chromium وWebKit على تنسيق الرسائل النصية القصيرة (SMS)، وأعلنت Apple عن إتاحة استخدام متصفّح Safari بدءًا من نظامَي iOS 14 وmacOS Big Sur. على الرغم من أنّ متصفّح Safari لا يتوافق مع WebOTP JavaScript API، إلا أنّه من خلال إضافة تعليق توضيحي إلى عنصر input باستخدام autocomplete=["one-time-code"]، تقترح لوحة المفاتيح التلقائية إدخال كلمة المرور لمرة واحدة (OTP) تلقائيًا إذا كانت الرسالة القصيرة SMS متوافقة مع التنسيق.

هل استخدام الرسائل القصيرة SMS كطريقة للمصادقة آمنة؟

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

أين يمكنني الإبلاغ عن أخطاء في تنفيذ Chrome؟

هل عثرت على خطأ في تنفيذ Chrome؟

  • عليك الإبلاغ عن الخطأ على https://new.crbug.com. ويُرجى تضمين أكبر قدر ممكن من التفاصيل، وإرشادات بسيطة لإعادة إنتاج الإصدار، وضبط المكونات على Blink>WebOTP.

كيف يمكنني تقديم المساعدة في هذه الميزة؟

هل تخطّط لاستخدام WebOTP API؟ يساعدنا الدعم المتاح للجميع في إعطاء الأولوية للميزات، كما يوضّح لمورّدي المتصفِّح الآخرين مدى أهمية دعمهم. يمكنك إرسال تغريدة إلى @ChromiumDev باستخدام علامة الهاشتاغ #WebOTP وإخبارنا بمكان استخدامك لهذه العلامة وكيفية استخدامها.

المراجِع