Flutter一次性密码生成与验证插件dart_otp的使用
Flutter一次性密码生成与验证插件dart_otp的使用
dart_otp
是一个用于生成和验证一次性密码(One-Time Password, OTP)的 Dart 包。它主要用于实现 Web 应用程序和其他需要登录系统的双因素认证(2FA)或多因素认证(MFA)。该包基于以下两个 RFC 实现:
特性
- 创建和验证基于计数器的 OTP 对象(HOTP)
- 创建和验证基于时间的 OTP 对象(TOTP)
- 生成包含 Base32 编码字符串的
otpauth URL
- 支持使用 SHA1、SHA256、SHA384 和 SHA512 进行 OTP token 加密
安装
Pubspec
在您的 pubspec.yaml
文件中添加 dart_otp
作为依赖项。
dependencies:
dart_otp: ^1.3.0
运行 flutter pub get
来安装依赖。
示例
基于时间的一次性密码(TOTP)
import 'package:dart_otp/dart_otp.dart';
void main() {
// 默认初始化为每30秒间隔和6位数字的令牌
TOTP totp = TOTP(secret: "J22U6B3WIWRRBTAV");
// 自定义间隔和数字值
TOTP totpCustom = TOTP(secret: "J22U6B3WIWRRBTAV", interval: 60, digits: 8);
// 获取当前时间的 OTP 值
print("当前 OTP: ${totp.now()}"); // 输出类似:432143
// 验证当前时间的 OTP
bool isValid = totp.verify(otp: 432143);
print("验证结果: $isValid"); // 输出:true
// 验证 30 秒后的 OTP
bool isExpired = totp.verify(otp: 432143);
print("过期验证结果: $isExpired"); // 输出:false
}
基于计数器的一次性密码(HOTP)
import 'package:dart_otp/dart_otp.dart';
void main() {
// 默认初始化为6位数字的令牌
HOTP hotp = HOTP(secret: "J22U6B3WIWRRBTAV");
// 自定义数字值
HOTP hotpCustom = HOTP(secret: "J22U6B3WIWRRBTAV", counter: 50, digits: 8);
// 获取指定计数器的 OTP 值
print("计数器 0 的 OTP: ${hotp.at(counter: 0)}"); // 输出类似:432143
print("计数器 2019 的 OTP: ${hotp.at(counter: 2019)}"); // 输出类似:231434
// 验证指定计数器的 OTP
bool isValidHotp = hotp.verify(otp: 231434, counter: 2019);
print("计数器验证结果: $isValidHotp"); // 输出:true
// 验证错误计数器的 OTP
bool isInvalidHotp = hotp.verify(otp: 231434, counter: 2020);
print("错误计数器验证结果: $isInvalidHotp"); // 输出:false
}
更多关于Flutter一次性密码生成与验证插件dart_otp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter一次性密码生成与验证插件dart_otp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dart_otp
是一个用于生成和验证一次性密码(OTP)的 Dart 包,支持基于时间的一次性密码(TOTP)和基于计数器的一次性密码(HOTP)。它非常适合在 Flutter 应用中实现双因素认证(2FA)功能。
安装 dart_otp
首先,你需要在 pubspec.yaml
文件中添加 dart_otp
依赖:
dependencies:
flutter:
sdk: flutter
dart_otp: ^2.0.0
然后运行 flutter pub get
来安装依赖。
使用 dart_otp
1. 生成 TOTP(基于时间的一次性密码)
TOTP 是基于当前时间生成的一次性密码,通常每 30 秒更新一次。
import 'package:dart_otp/dart_otp.dart';
void main() {
// 创建一个 TOTP 实例
final totp = TOTP(secret: 'your_secret_key');
// 生成当前时间的一次性密码
final otp = totp.now();
print('Generated OTP: $otp');
}
2. 验证 TOTP
你可以使用 verify
方法来验证用户输入的 OTP 是否正确。
import 'package:dart_otp/dart_otp.dart';
void main() {
final totp = TOTP(secret: 'your_secret_key');
// 假设用户输入的 OTP 是 '123456'
final userOtp = '123456';
// 验证 OTP
final isValid = totp.verify(userOtp);
print('Is OTP valid? $isValid');
}
3. 生成 HOTP(基于计数器的一次性密码)
HOTP 是基于计数器生成的一次性密码,每次生成 OTP 时计数器都会递增。
import 'package:dart_otp/dart_otp.dart';
void main() {
// 创建一个 HOTP 实例
final hotp = HOTP(secret: 'your_secret_key', counter: 0);
// 生成当前计数器的一次性密码
final otp = hotp.generate();
print('Generated OTP: $otp');
// 递增计数器
hotp.incrementCounter();
}
4. 验证 HOTP
与 TOTP 类似,你可以使用 verify
方法来验证 HOTP。
import 'package:dart_otp/dart_otp.dart';
void main() {
final hotp = HOTP(secret: 'your_secret_key', counter: 0);
// 假设用户输入的 OTP 是 '123456'
final userOtp = '123456';
// 验证 OTP
final isValid = hotp.verify(userOtp);
print('Is OTP valid? $isValid');
}
注意事项
-
Secret Key:
secret
是生成 OTP 的关键,通常是一个 Base32 编码的字符串。确保它足够安全,并且不要硬编码在代码中。 -
TOTP 时间窗口: TOTP 默认使用 30 秒的时间窗口。你可以通过
interval
参数来调整这个时间窗口。 -
HOTP 计数器: HOTP 的计数器需要在使用后递增,以确保每次生成的 OTP 都是唯一的。
示例应用
你可以在 Flutter 应用中使用 dart_otp
来实现双因素认证功能。例如,在用户登录时生成一个 TOTP,并要求用户输入该 OTP 以完成登录。
import 'package:flutter/material.dart';
import 'package:dart_otp/dart_otp.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: OTPDemo(),
);
}
}
class OTPDemo extends StatefulWidget {
[@override](/user/override)
_OTPDemoState createState() => _OTPDemoState();
}
class _OTPDemoState extends State<OTPDemo> {
final _otpController = TextEditingController();
final _totp = TOTP(secret: 'your_secret_key');
void _verifyOTP() {
final userOtp = _otpController.text;
final isValid = _totp.verify(userOtp);
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('OTP Verification'),
content: Text(isValid ? 'OTP is valid!' : 'OTP is invalid!'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('OTP Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: _otpController,
decoration: InputDecoration(labelText: 'Enter OTP'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _verifyOTP,
child: Text('Verify OTP'),
),
],
),
),
);
}
}