在 Web 中自动读取 OTP 并从 Web 中的剪贴板复制粘贴 OTP 不适用于 Android/iOS

jar*_*vak 4 javascript android autofill reactjs ionic-react

我正在使用Ionic React应用程序,对于构建 ionic React 应用程序来说是全新的。目前,我正在尝试通过在用户登录/注册期间获取android/iOSOTP的直通消息来自动填充 OTP(一次性密码) 。目前,每次新注册/登录时,OTP 都会通过默认 SMS 服务发送给用户。因此,当 OTP 到达用户时,用户可以手动键入 OTP,也可以从消息中复制 OTP 并将其粘贴到 Web 应用程序中。因此,目前用户可以从消息中复制 OTP 并粘贴(有将触发的handlePaste函数),但是Twilio's

提出我面临的问题

  • 当 OTP 到达时,手机键盘中 OTP 的建议不会出现在 Android 中,但可以在 iOS 中显示。
  • 当用户从消息中复制 OTP 并返回应用程序并单击输入字段时,网络键盘将显示在键盘中复制的 OTP。现在,如果用户单击该 OTP,则仅填充输入字段的第一个字段,其他字段保留为空(使用 4 个单独的输入字段),并且不会触发handlePaste函数。
  • 我尝试在粘贴函数中添加控制台/警报,但没有记录任何内容。

短信格式

Your OTP is: 123456.

@domain.com #123456

Run Code Online (Sandbox Code Playgroud)

到目前为止尝试过的方法:

处理粘贴函数代码:

const length = 6;
const [activeInput, setActiveInput] = useState(0)
const [otpValues, setOTPValues] = useState(Array<string>(length).fill(''))


    const handleOnPaste = 
    (e: React.ClipboardEvent<HTMLInputElement>) => {
        e.preventDefault()
        const pastedData = e.clipboardData
            .getData('text/plain')
            .trim()
            .slice(0, length - activeInput)
            .split('')
        if (pastedData) {
            let nextFocusIndex = 0
            const updatedOTPValues = [...otpValues]
            updatedOTPValues.forEach((val, index) => {
                
                    console.log(pastedData)
                        nextFocusIndex = index
                    
                
            })
            setActiveInput(Math.min(nextFocusIndex + 1, length - 1))
        }
    }
Run Code Online (Sandbox Code Playgroud)

导航器凭据代码在函数内部使用但不起作用:

navigator.credentials.get({
  otp: { transport:['sms'] },
  signal: ac.signal
}).then((otp) => {
  console.log(otp)
  
}).catch((err) => {
  console.error(err);
});


Run Code Online (Sandbox Code Playgroud)

如果有人能帮助我,我将非常感激:)

小智 8

问题实际上出在 iOS/android 手机的网络浏览器上。在移动网络浏览器中,当从键盘剪贴板粘贴文本/数字时,该onPaste功能永远不会被触发。看起来像这样。

从消息中自动读取 OTP

因此,简而言之,您的handlePaste函数永远不会被触发,并且您永远不会在其中clipboardData 获取值onchange,但您的元素函数input 会被触发。

解决方案

  1. 您可以做的是,在onChange函数内检查输入值。
  2. 检查value长度是否大于1。
  3. 如果大于1,则手动将数据添加到clipboardData
  4. 然后调用该handlePaste函数。

代码

将其添加到您的onChange函数中。

const handleChange = (e) => {
  const val = e.target.value;

  if (!val) {
    e.preventDefault();
    return;
  }

  // add this condition to manually trigger the paste
  // function and manually send the value to clipboard

  else if (val.trim().length > 1) {
    e.clipboardData = {
      getData: () => val.trim(),
    };
    handleOnPaste(e);
  } else {

    // do any other required changes
  }
};


Run Code Online (Sandbox Code Playgroud)

OTP这将解决您仅在单个输入中填写的问题。

  • 这个实现有一个问题。根据我的经验,粘贴会逐个进行,每次都会触发一个更改事件 - 例如,如果您的代码是 1234 - 您将获得 4 个更改事件,其值为“1”、“12”、“123”、“ 1234'。因此,您不仅需要 val.length &gt; 1 的条件,而且还需要 val.length === yourCodeLength。出去要注意安全。 (2认同)