我能在移动浏览器上自动读取OTP吗?

15

我正在研究如何自动读取移动浏览器上的登录OTP。我的Web应用是基于Angular 7构建的。

一旦用户点击登录,AWS会向用户的手机发送一个带有6位数字代码的OTP。

我已经查阅了Google的SMS Retriever API,但它对我的情况没有帮助。

从移动浏览器中读取OTP是否可能?

4个回答

16

这是一个老问题,在问题发布时,不可能

但现在我们可以在移动浏览器上读取OTP

使用WEBOTP API,我们可以检测移动设备上的网页OTP。

您可以使用以下代码检查此功能是否适用于您的浏览器

if (!window.OTPCredential) {
  console.log('Feature Not Available');
}
else{
  console.log('Feature Available');
}

注意:如果您在笔记本电脑或台式机上进行测试,则上述代码将显示“功能不可用”。要在笔记本电脑或台式机上进行测试,您需要将切换器更改为移动设备。 SMS Receiver API JavaScriptWeb OTP API W3C Community 您可以在上面的链接中获取文档。
在使用OTPCredential之前,我们需要有AbortController,它将用于在一段时间后(可以基于时间或读取短信后)禁用WebOTP API(自动读取短信)。
 const ac = new AbortController();
 setTimeout(() => {
   ac.abort();
 }, 1 * 60 * 1000);

在上述代码中,WebOTP API将在1分钟后终止。

您可以拥有这种类型的HTML表单

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

现在,用户在他们的移动设备上接收到的短信格式将如下所示。

@BOUND_DOMAIN #OTP_CODE

以上行可以是您的短信的最后一行

  • @BOUND_DOMAIN 将是您的网站域名,例如 @www.examle.com
  • #OTP_CODE 将是用于身份验证的 OTP,例如 #1234(请保持在 4 到 6 位数字之间)。

因此,短信格式将类似于以下内容:

Hi User, please do not share your OTP with anyone.
@www.example.com #123456

为了调用WebOTP API,我们需要了解Web Authentication API
 navigator.credentials.get([options])

需要使用上述代码来调用WebOTP API

 navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal //This is from the AbortController
 }).then(otp => {
      input.value = otp.code;
      // Automatically submit the form when an OTP is obtained.
 }).catch(err => {
      console.log(err);
 });

现在,以下是演示代码

HTML 代码:

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

JavaScript 代码:

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    // Cancel the Web OTP API if the form is submitted manually.
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        // Cancel the Web OTP API.
        ac.abort();
      });
    }
    // Invoke the Web OTP 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);
    });
  });
}

SMS格式可以是这样的:

Hi, this is a demo OTP
@www.mydomain.com #1234



OYO(他们的技术博客)这样的公司使用了这个功能。

注意- 目前它还处于开发阶段,仅适用于Chrome 78


2020年更新
Chrome 84开始,它已正式推出。但仍有许多改进正在进行中。


API是否可以访问整个短信收件箱,或者它是如何工作的?就像我必须根据域读取cookie一样...那么API可以获得什么访问权限? - copenndthagen
@NotABot 但问题在于用户的收件箱中可能有数百条短信...API如何读取?它是否可以访问所有消息,以及如何解析OTP(基于最近的消息等)? - copenndthagen
@AsfarIrshad 是的,你说得对,也许发布被延迟了,但beta版本仍然支持不正确和一些先前的Chrome版本。当我写这个答案时,我认为这就是告诉我要在其中启动此API的浏览器。现在它被推迟到Chrome 81。 - Not A Bot
@testndtv 从用户的短信箱中获取的浏览器JSON对象必须具有某种类型的关键字“OTP”和其他您的Web应用程序设置的关键字,例如“myApp”:“My Test APP”。就像这样,浏览器仅获取与这些条件匹配的OTP,但是此方法存在限制,黑客可以模仿此操作并获取用户的OTP。 - Not A Bot
1
@testndtv 在这里你可以获取代码以及对它的良好解释,了解它是如何工作的。 - Not A Bot
显示剩余7条评论

15

是的,现在这是可能的。Chrome在84版本及以上发布了此功能。利用WEBOTP API,我们可以在移动设备的Web上检测到OTP。

代码 -

if ('OTPCredential' in window) { 
  window.addEventListener('DOMContentLoaded', e => {
    const ac = new AbortController();
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      alert(otp.code)
    }).catch(err => {
      console.log(err)
    });
  })
} else {
  alert('WebOTP not supported!.')
}

SMS格式 -

@www.amazon.com #1598.

在@www.amazon.com这个域名下进行验证,1598是一次性密码

演示链接- https://jyotishman.github.io/webOTPAPI/


1
很好!这里是官方的谷歌页面,链接为https://web.dev/web-otp/。 - menepet
我在使用TypeScript的Angular时遇到了缺少类型定义的问题。 - Harkirat singh
我现在看不到短信中的URL。答案需要更新。例如短信中的“349340是Trxn的OTP。您的信用卡末尾为56,支付了351.00卢比的Xyz co P。 OTP有效期为10分钟。请勿与任何人分享-SBI卡”。也许需要指定发送者ID?或者一个模板,该服务会在收到短信后的几分钟内查找它。 - tgkprog

0
任何类型的浏览器都只能访问浏览器数据,这是出于安全目的。因为在浏览器中运行的网站无法访问浏览器外部,所以您无法在网站上访问手机上收到的 OTP。
一般的规则是,网站无法访问文件系统,因此禁止任何浏览器外部的功能。
如果您正在构建原生应用程序,则可以通过权限访问它。

0

简而言之,这是不可能的。因为移动设备无法访问文件系统。请使用React Native或类似技术。

我在搜索问题时发现了一个名为“https://web.dev/web-otp/” 的网站。它可能有所帮助,但我还没有实施过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接