شماره تلفن های موجود در وب را با WebOTP API تأیید کنید

به کاربران با OTP های دریافت شده از طریق پیامک کمک کنید

ایجی کیتامورا
ایجی کیتامورا

WebOTP API چیست؟

این روزها، اکثر مردم جهان صاحب یک دستگاه تلفن همراه هستند و توسعه دهندگان معمولاً از شماره تلفن به عنوان شناسه کاربران خدمات خود استفاده می کنند.

روش‌های مختلفی برای تأیید شماره تلفن وجود دارد، اما رمز عبور یک‌بار مصرف (OTP) که به‌طور تصادفی ایجاد می‌شود، ارسال شده توسط پیامک یکی از رایج‌ترین آنهاست. ارسال این کد به سرور توسعه دهنده کنترل شماره تلفن را نشان می دهد.

این ایده در حال حاضر در بسیاری از سناریوها برای دستیابی به موارد زیر به کار گرفته شده است:

  • شماره تلفن به عنوان شناسه برای کاربر. هنگام ثبت نام برای یک سرویس جدید، برخی از وب سایت ها به جای آدرس ایمیل یک شماره تلفن می خواهند و از آن به عنوان شناسه حساب استفاده می کنند.
  • تایید دو مرحله ای هنگام ورود به سیستم، یک وب سایت برای امنیت بیشتر، یک کد یکبار مصرف از طریق پیامک در کنار رمز عبور یا سایر فاکتورهای دانش درخواست می کند.
  • تاییدیه پرداخت. هنگامی که کاربر در حال پرداخت است، درخواست یک کد یکبار مصرف ارسال شده از طریق پیامک می تواند به تأیید قصد شخص کمک کند.

روند فعلی باعث ایجاد اصطکاک برای کاربران می شود. یافتن یک OTP در یک پیام اس ام اس، سپس کپی و چسباندن آن در فرم دشوار است و نرخ تبدیل را در سفرهای حیاتی کاربر کاهش می دهد. کاهش این امر یک درخواست طولانی مدت برای وب از سوی بسیاری از بزرگترین توسعه دهندگان جهانی بوده است. اندروید یک API دارد که دقیقاً این کار را انجام می دهد . iOS و Safari هم همینطور.

WebOTP API به برنامه شما اجازه می‌دهد پیام‌هایی با قالب‌بندی خاص به دامنه برنامه شما دریافت کند. از این طریق می توانید به صورت برنامه ریزی شده یک OTP را از یک پیام کوتاه دریافت کنید و یک شماره تلفن را برای کاربر راحت تر تأیید کنید.

آن را در عمل ببینید

فرض کنید یک کاربر می خواهد شماره تلفن خود را با یک وب سایت تأیید کند. وب سایت یک پیام متنی برای کاربر از طریق پیامک ارسال می کند و کاربر OTP را از پیام وارد می کند تا مالکیت شماره تلفن را تأیید کند.

همانطور که در ویدیو نشان داده شده است، با WebOTP API، این مراحل به آسانی یک ضربه برای کاربر است. هنگامی که پیام متنی می رسد، یک برگه پایین ظاهر می شود و از کاربر می خواهد شماره تلفن خود را تأیید کند. پس از کلیک بر روی دکمه Verify در صفحه پایین، مرورگر OTP را در فرم قرار می دهد و فرم بدون نیاز به فشار دادن Continue توسط کاربر ارسال می شود.

کل فرآیند در تصویر زیر نشان داده شده است.

نمودار WebOTP API

خود دمو را امتحان کنید. شماره تلفن شما را نمی‌خواهد یا پیامکی به دستگاه شما نمی‌فرستد، اما می‌توانید با کپی کردن متن نمایش داده شده در نسخه نمایشی، آن را از دستگاه دیگری ارسال کنید. این کار می کند زیرا هنگام استفاده از WebOTP API فرقی نمی کند فرستنده چه کسی باشد.

  1. در Chrome 84 یا جدیدتر در دستگاه Android به https://web-otp.glitch.me بروید.
  2. پیامک زیر را از تلفن دیگری به تلفن خود ارسال کنید.
Your OTP is: 123456.

@web-otp.glitch.me #12345

آیا پیامک را دریافت کردید و اعلان وارد کردن کد را در قسمت ورودی مشاهده کردید؟ به این ترتیب WebOTP API برای کاربران کار می کند.

استفاده از WebOTP API از سه بخش تشکیل شده است:

  • یک تگ <input> با حاشیه نویسی مناسب
  • جاوا اسکریپت در برنامه وب شما
  • متن پیام فرمت شده از طریق پیامک ارسال می شود.

ابتدا تگ <input> را پوشش خواهم داد.

یک برچسب <input> حاشیه نویسی کنید

WebOTP خود بدون هیچ گونه حاشیه نویسی HTML کار می کند، اما برای سازگاری بین مرورگرها، به شدت توصیه می کنم که autocomplete="one-time-code" به تگ <input> در جایی که انتظار دارید کاربر یک OTP وارد کند، اضافه کنید.

این به Safari 14 یا جدیدتر اجازه می‌دهد تا زمانی که کاربر پیامکی با فرمت توضیح داده شده در فرمت پیام SMS دریافت می‌کند، حتی اگر از WebOTP پشتیبانی نمی‌کند، فیلد <input> را به‌طور خودکار با یک OTP پر کند.

HTML

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

از WebOTP API استفاده کنید

از آنجایی که WebOTP ساده است، فقط کپی و چسباندن کد زیر این کار را انجام می دهد. به هر حال من شما را از آنچه در حال رخ دادن است راهنمایی خواهم کرد.

جاوا اسکریپت

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);
    });
  });
}

تشخیص ویژگی

تشخیص ویژگی مانند بسیاری از API های دیگر است. گوش دادن به رویداد DOMContentLoaded منتظر می ماند تا درخت DOM برای پرس و جو آماده شود.

جاوا اسکریپت

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 خود به اندازه کافی ساده است. برای دریافت OTP navigator.credentials.get() استفاده کنید. WebOTP یک گزینه otp جدید به آن روش اضافه می کند. فقط یک ویژگی دارد: transport ، که مقدار آن باید آرایه ای با رشته 'sms' باشد.

جاوا اسکریپت

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

این جریان مجوز مرورگر را هنگامی که یک پیام اس ام اس می رسد فعال می کند. اگر مجوز داده شود، وعده بازگشتی با یک شی OTPCredential حل می شود.

محتوای شی OTPCredential به دست آمده

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

سپس مقدار OTP را به فیلد <input> منتقل کنید. ارسال مستقیم فرم مرحله ای را که کاربر باید روی دکمه ضربه بزند حذف می کند.

جاوا اسکریپت

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

لغو پیام

در صورتی که کاربر به صورت دستی یک OTP را وارد کرده و فرم را ارسال کند، می‌توانید با استفاده از یک نمونه AbortController در شی options ، تماس get() را لغو کنید.

جاوا اسکریپت

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

پیامک را فرمت کنید

خود API باید به اندازه کافی ساده به نظر برسد، اما چند نکته وجود دارد که باید قبل از استفاده از آن بدانید. پیام باید پس از فراخوانی navigator.credentials.get() ارسال شود و باید در دستگاهی که get() فراخوانی شده است دریافت شود. در نهایت، پیام باید به قالب بندی زیر پایبند باشد:

  • پیام با متن قابل خواندن برای انسان (اختیاری) آغاز می شود که شامل یک رشته الفبایی 4 تا 10 کاراکتری با حداقل یک عدد است که آخرین خط را برای URL و OTP باقی می گذارد.
  • قسمت دامنه URL وب سایتی که API را فراخوانی کرده است باید قبل از @ باشد.
  • URL باید دارای یک علامت پوند (' # ') باشد که با OTP همراه باشد.

مثلا:

Your OTP is: 123456.

@www.example.com #123456

در اینجا نمونه های بد وجود دارد:

مثال متن پیامک نادرست چرا این کار نخواهد کرد
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 یک پیام کوتاه حاوی یک OTP برای کاربر می فرستد تا بتواند آن را برای تایید هویت خود وارد کند.

برای استفاده از WebOTP API از داخل یک iframe متقاطع، باید دو کار را انجام دهید:

  • منشاء فریم بالا و مبدا iframe را در پیام متنی پیامک حاشیه نویسی کنید.
  • خط مشی مجوزها را پیکربندی کنید تا به 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-credentials به این API دسترسی دهد تا از رفتار ناخواسته جلوگیری شود. به طور کلی دو راه برای رسیدن به این هدف وجود دارد:

از طریق HTTP Header:

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

از طریق ویژگی iframe allow :

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

مثال های بیشتری در مورد نحوه تعیین یک خط مشی مجوز ببینید.

از WebOTP در دسکتاپ استفاده کنید

در Chrome، WebOTP از گوش دادن به پیامک‌های دریافتی در دستگاه‌های دیگر پشتیبانی می‌کند تا به کاربران در تکمیل تأیید شماره تلفن در دسک‌تاپ کمک کند.

WebOTP API روی دسکتاپ.

این قابلیت به کاربر نیاز دارد که هم در کروم دسکتاپ و هم در اندروید کروم به یک حساب Google وارد شود.

تنها کاری که توسعه دهندگان باید انجام دهند این است که WebOTP API را در وب سایت دسکتاپ خود پیاده سازی کنند، به همان روشی که در وب سایت تلفن همراه خود انجام می دهند، اما هیچ ترفند خاصی لازم نیست.

جزئیات بیشتر را در تأیید شماره تلفن روی دسکتاپ با استفاده از WebOTP API بیاموزید.

سوالات متداول

گفت و گو ظاهر نمی شود اگرچه من پیامی با فرمت مناسب ارسال می کنم. چه مشکلی دارد؟

هنگام آزمایش API چند نکته وجود دارد:

  • اگر شماره تلفن فرستنده در فهرست تماس گیرنده گنجانده شود، به دلیل طراحی API رضایت کاربر پیامک زیربنایی، این API فعال نخواهد شد.
  • اگر از یک نمایه کاری در دستگاه Android خود استفاده می‌کنید و WebOTP کار نمی‌کند، سعی کنید Chrome را در نمایه شخصی خود نصب و از آن استفاده کنید (یعنی همان نمایه‌ای که در آن پیام‌های SMS دریافت می‌کنید).

دوباره قالب را بررسی کنید تا ببینید پیامک شما به درستی قالب بندی شده است یا خیر.

آیا این API بین مرورگرهای مختلف سازگار است؟

Chromium و WebKit بر سر قالب پیام متنی اس ام اس توافق کردند و اپل از پشتیبانی سافاری از آن در iOS 14 و macOS Big Sur خبر داد . اگرچه Safari از WebOTP JavaScript API پشتیبانی نمی‌کند، با حاشیه‌نویسی عنصر input با autocomplete=["one-time-code"] ، صفحه‌کلید پیش‌فرض به‌طور خودکار پیشنهاد می‌کند که اگر پیام SMS با قالب مطابقت دارد، OTP را وارد کنید.

آیا استفاده از پیامک به عنوان روشی برای احراز هویت بی خطر است؟

در حالی که SMS OTP برای تأیید شماره تلفن هنگام ارائه شماره برای اولین بار مفید است، تأیید شماره تلفن از طریق پیامک باید برای احراز هویت مجدد به دقت مورد استفاده قرار گیرد زیرا شماره‌های تلفن می‌توانند توسط شرکت‌های مخابراتی ربوده و بازیافت شوند. WebOTP یک مکانیزم احراز هویت مجدد و بازیابی مناسب است، اما سرویس ها باید آن را با عوامل اضافی مانند چالش دانش ترکیب کنند یا از Web Authentication API برای احراز هویت قوی استفاده کنند.

کجا می توانم اشکالات پیاده سازی کروم را گزارش کنم؟

آیا اشکالی در پیاده سازی کروم پیدا کردید؟

  • یک اشکال را در https://new.crbug.com ثبت کنید. تا جایی که می توانید جزئیات، دستورالعمل های ساده برای بازتولید را وارد کنید و Components را روی Blink>WebOTP تنظیم کنید.

چگونه می توانم به این ویژگی کمک کنم؟

آیا قصد دارید از WebOTP API استفاده کنید؟ پشتیبانی عمومی شما به ما کمک می کند تا ویژگی ها را اولویت بندی کنیم و به سایر فروشندگان مرورگر نشان می دهد که چقدر حمایت از آنها ضروری است. با استفاده از هشتگ #WebOTP یک توییت به ChromiumDev@ ارسال کنید و به ما اطلاع دهید کجا و چگونه از آن استفاده می‌کنید.

منابع