Flutter中Google Authenticator OTP验证失败问题求助
解决Flutter中TOTP验证不一致的问题
你的问题核心在于两个关键错误,导致本地生成的OTP和验证器应用生成的不一致:
1. OTP URI参数分隔符错误
你在_generateTOTPUrl方法中使用了HTML转义字符&作为参数分隔符,但OTP的otpauth:// URI要求使用普通的&来分隔参数。这会导致验证器应用解析URI时出现异常,虽然能显示OTP,但实际使用的配置可能和本地验证逻辑不匹配。
修复方法:把所有&替换为&:
String _generateTOTPUrl({ @required String? secret, @required String? accountName, @required String? issuer, String algorithm = 'SHA1', int digits = 6, int period = 30, }) { return 'otpauth://totp/${Uri.encodeComponent(accountName!)}?secret=$secret&issuer=${Uri.encodeComponent(issuer!)}&algorithm=$algorithm&digits=$digits&period=$period'; }
2. 时间戳计算的精度问题
你当前的时间计算使用了浮点除法后floor(),可能会因为浮点精度误差导致时间戳计算错误。改用Dart的整数除法~/可以避免这个问题,同时显式指定period参数确保和URI配置一致。
修复_verifyOtp方法中的时间计算逻辑:
void _verifyOtp() async { if (_otpController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Enter OTP')), ); return; } bool isCodeValid = false; int currentTimeSeconds = DateTime.now().millisecondsSinceEpoch ~/ 1000; for (int i = -1; i <= 1; i++) { int timestamp = currentTimeSeconds + i * 30; String generatedCode = OTP.generateTOTPCodeString( _otpSecret!, timestamp, algorithm: Algorithm.SHA1, length: 6, period: 30, ); print(generatedCode); if (_otpController.text == generatedCode) { isCodeValid = true; break; } } if (isCodeValid) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('OTP verified successfully!')), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Incorrect OTP code')), ); } }
额外检查项
- 确保设备开启自动时间同步:TOTP完全依赖准确的UTC时间,时间偏差会导致OTP不一致。
- 验证密钥一致性:扫描二维码后,在验证器应用中查看存储的密钥,确认和本地打印的
_otpSecret完全一致(Base32大小写不敏感,部分验证器会统一转为大写)。
内容的提问来源于stack exchange,提问作者Wytex System
相关产品推荐
相关产品推荐

