使用Google Authenticator应用程序验证OTP



我已经在我的应用程序中实现了2因素身份验证,但我无法验证我的应用程序和Google Authenticator应用程序中生成的OTP,我的应用程序中生成的OTP与Authenticator应用程序非常不同。

下面是我如何在我的应用程序中生成OTP:
var otpStream = Stream<dynamic>.periodic(
const Duration(seconds: 1),
(val) => OTP.generateTOTPCodeString(
'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch,
length: 6,
interval: 30,
algorithm: Algorithm.SHA256,
isGoogle: true)).asBroadcastStream();

这里我使用一个流,这样我就可以不断地听到OTP每秒钟的变化,用于开发目的

我使用这个包来生成OTP: https://pub.dev/packages/otp

在google authenticator应用程序中注册我的应用程序时,我显示QR码,其内容为otpauth://totp/companyName?secret=JBSWY3DPEHPK3PXP&issuer=ClientID&period=30

密钥已经是base32格式,并且被认证器应用接受。

如果我做错了什么,请让我知道,因为这是我第一次实现这样的功能。

答案

在花了一段时间工作后发现了一个新手错误,发现我显示的QR没有传递正确的哈希算法,所以我改变了OTP生成器函数,现在有一个正确的哈希算法,QR现在传递正确的算法

这里是在应用程序中收听OTP的更改后的流:

var otpStream = Stream<dynamic>.periodic(
const Duration(seconds: 0),
(val) => OTP.generateTOTPCodeString(
'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch,
length: 6,
interval: 30,
algorithm: Algorithm.SHA1,
isGoogle: true)).asBroadcastStream();

, QR的数据如下:(注意*去掉URI上所有的花括号)

otpauth://totp/{CompanyName:clientID}?Algorithm=SHA1&digits=6&secret={yourbase32key}&issuer={CompanyName}&period=30

您可以在initState(() {});中添加一个变量来订阅流,如下所示:

import "dart:async";
late StreamSubscription _twoFASubscription;
var _currentOtp;
@override
void initState() {
_twoFASubscription = otpStream.listen((event) {
setState(() {
_currentOtp = event;
});
});
super.initState();
}

也在完成OTP更改后,不要忘记调用dispose()方法从流中取消订阅,如下所示:

@override
void dispose() {
_twoFASubscription.cancel();
super.dispose();
}

TL;博士

确保您传递给QR的参数与您在应用程序中用于生成OTP的参数相同

最新更新