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

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

ما هي WebOTP API؟

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

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

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

  • رقم الهاتف كمعرّف للمستخدِم. عند الاشتراك في خدمة جديدة، تطلب بعض المواقع الإلكترونية رقم هاتف بدلاً من عنوان البريد الإلكتروني وتستخدمه كمعرّف حساب.
  • التحقّق بخطوتين: عند تسجيل الدخول، يطلب أحد المواقع الإلكترونية رمزًا يُستخدم لمرة واحدة يتم إرساله عبر رسالة قصيرة 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 حتى تصبح شجرة DOM جاهزة لطلب البحث.

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() للحصول على كلمة المرور لمرة واحدة (OTP). تضيف 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) عبر رسالة قصيرة SMS إلى إطار iframe من مصادر متعددة لتأكيد الدفع، خاصةً مع نظام 3D Secure. توفّر واجهة WebOTP API التنسيق المشترك لدعم إطارات iframe من مصادر متعددة، إذ توفّر لك واجهة برمجة التطبيقات WebOTP API كلمات المرور المرتبطة بمصادر متداخلة. على سبيل المثال:

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

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

  • أضِف تعليقات توضيحية على كل من أصل الإطار العلوي وأصل iframe في الرسالة النصية القصيرة (SMS).
  • يمكنك ضبط سياسة الأذونات للسماح لإطار iframe متعدد المصادر بتلقّي كلمة المرور لمرة واحدة (OTP) من المستخدم مباشرةً.
WebOTP API داخل إطار 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")

من خلال سمة allow إطار iframe:

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

مزيد من الأمثلة حول كيفية تحديد سياسة أذونات

استخدام WebOTP على الكمبيوتر المكتبي

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

هل واجهت خطأً في تنفيذ Chrome؟

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

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

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

المراجِع