10

我想在我的android应用程序中实现OTP 功能。在此应用程序中,注册用户后将收到一次密码密钥验证 OTP后,用户将能够使用该 OTP成功注册/开户。我需要做些什么来实现这一目标?

4

3 回答 3

11

我已经实现了一个非常简单的 OTP 方法..

  1. Activity 生成一个随机的 5 位数字,并通过 SMS 网关将其发送到手机号码。
  2. 在接收短信时,广播接收器读取短信正文并将代码从短信正文复制到 OTP EditText。
  3. 如果活动生成的随机代码和通过短信发送的代码相同,则用户应该获得进一步的访问权限。
于 2014-12-23T12:20:47.447 回答
9

检查谷歌身份验证器。https://code.google.com/p/google-authenticator/它是具有 OTP 功能的开源项目

安卓应用程序源代码https://code.google.com/p/google-authenticator/source/browse/?repo=android

这是服务器端的源代码https://github.com/chregu/GoogleAuthenticator.php

维基百科文章http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm

于 2014-03-14T09:02:36.773 回答
5

正如@Vipin 提到的,最好的方法是自己实现它:

首先,您必须生成一个 4 位(或任何您想要的)密码,例如:

int range = 9;  // to generate a single number with this range, by default its 0..9
int length = 4; // by default length is 4

public int generateRandomNumber() {
    int randomNumber;

    SecureRandom secureRandom = new SecureRandom();
    String s = "";
    for (int i = 0; i < length; i++) {
        int number = secureRandom.nextInt(range);
        if (number == 0 && i == 0) { // to prevent the Zero to be the first number as then it will reduce the length of generated pin to three or even more if the second or third number came as zeros
            i = -1;
            continue;
        }
        s = s + number;
    }

    randomNumber = Integer.parseInt(s);

    return randomNumber;
}

然后,您必须将此号码保存在某个地方,例如在您的首选项中:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("OTP_PIN", randomNumber);
editor.commit();

下一步,将使用适当的 SMS 网关将该 OTP 发送到相应的电话号码,对我来说,我正在使用clickAtell和我们的 php 服务器来发送消息,api 文档非常清楚。如果您想直接从应用程序发送消息,可能SMSgateway可以提供帮助。

最后一步,是验证短信接收到的代码是存储在设备偏好中的代码,这非常简单直接,您所要做的就是为EditText用户提供一个允许他输入手机接收到的代码,如果代码与设备偏好中保存的 OTP 匹配,则让他通过应用程序,否则,显示正确的错误消息。


一个优雅的举动: 不是强制性的,但最好是,因为很多应用程序可以提供 SMS 监听器来收听即将到来的消息,从收到的消息中获取代码,在代码验证中显示它editText,验证它,如果为真,通过应用程序。

manifest.xml中:

<receiver
    android:name=".Services.SmsListener"
    android:exported="true"
    android:permission="android.permission.BROADCAST_SMS">
    <intent-filter android:priority="999">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

听众:

public class SmsListener extends BroadcastReceiver {

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("messageBody", intent.getAction());
        if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
            try {
                String messageBody = "";
                for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
                    messageBody = smsMessage.getMessageBody();
                }
                Intent messageReceived = new Intent(SVPreferences.SMS_RECEIVED);
                messageReceived.putExtra("sms", messageBody);
                context.sendBroadcast(messageReceived); // when receiving it somewhere in your app, subString the additional text and leave only the code, then place it in the editText and do your verification
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

收件人:

BroadcastReceiver receiveSMS = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String smsBody = intent.getStringExtra("sms");
            String pin = smsBody.replace(getResources().getString(R.string.your_extra_text), "").trim();
            editText_confirm_pin.setText(pin);
            if (validatePin(pin))
                // go through the app
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
};
于 2017-09-18T07:19:01.610 回答