Flutter一次性密码(TOTP)认证插件auth_totp的使用
Flutter一次性密码(TOTP)认证插件auth_totp的使用
auth_totp
是一个快速且易于使用的基于时间的一次性密码(TOTP)认证包,适用于你的Flutter应用。它与 Google Authenticator
、1Password
、LastPass
、Microsoft Authenticator
以及其他各种认证应用程序兼容。
Get Started
Create Secret Key 🔑
生成一个随机的秘密密钥,用于从认证应用程序创建验证码。
String secret = AuthTOTP.createSecret(
length: 16,
autoPadding: true,
secretKeyStyle: SecretKeyStyle.upperLowerCase
);
// 输出示例:xHu6 nh7I D8uI s9B1
length
: 密钥长度,默认值为32,范围在16到255之间。autoPadding
: 是否自动填充,将密钥分为每4个字符一组,默认为false。secretKeyStyle
: 密钥风格,可以是大写、小写或大小写混合。
Verify TOTP Code ✔️
验证用户输入的TOTP代码是否正确。
bool checkOTP = AuthTOTP.verifyCode({
secretKey: "secret_key_here",
totpCode: "totp_code_here_by_user",
interval: 30
});
secretKey
: 使用createSecret
方法生成的秘密密钥。totpCode
: 用户输入的TOTP代码。interval
: 时间间隔,默认为30秒。
Generate TOTP Code 🚀
根据秘密密钥和时间间隔生成TOTP代码。
String generatedTOTPCode = AuthTOTP.generateTOTPCode(
secretKey: 'secret_key_here',
interval: 30
);
Get QR Code to Scan 📸
返回一个二维码URL,用户可以通过认证应用程序扫描该二维码。
String qrCodeUrl = AuthTOTP.getQRCodeUrl({
appName: "your app name",
secretKey: "secret_key_here",
issuer:"auth_totp"
});
// Image.Network(qrCodeUrl);
Full Example
以下是一个完整的示例,展示了如何使用auth_totp
插件。
import 'package:auth_totp/auth_totp.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: QRCodePage(),
),
);
}
class QRCodePage extends StatefulWidget {
const QRCodePage({super.key});
@override
State<QRCodePage> createState() => _QRCodePageState();
}
class _QRCodePageState extends State<QRCodePage> {
String secret = AuthTOTP.createSecret(
length: 16,
autoPadding: true,
secretKeyStyle: SecretKeyStyle.upperLowerCase);
String appName = "TOTP"; // 给出你的应用名称
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Auth TOTP Flutter Package", style: TextStyle(color: Colors.white)),
centerTitle: true,
backgroundColor: Colors.green,
elevation: 0,
shadowColor: Colors.transparent,
),
body: ListView(
padding: const EdgeInsets.all(16.0),
children: [
const Center(
child: Text("扫描此二维码或将秘密代码复制到您的认证应用中。点击继续进行验证。"),
),
Image.network(AuthTOTP.getQRCodeUrl(appName: appName, secretKey: secret)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: TextEditingController(text: secret),
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Secret Code',
),
readOnly: true,
),
),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VerificationPage(secret: secret),
),
);
},
child: const Text("Continue to Verify"),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
secret = AuthTOTP.createSecret(
length: 16,
autoPadding: true,
secretKeyStyle: SecretKeyStyle.upperLowerCase);
print(AuthTOTP.generateTOTPCode(secretKey: secret, interval: 30));
});
},
child: const Icon(Icons.refresh),
),
);
}
}
class VerificationPage extends StatefulWidget {
final String secret;
const VerificationPage({super.key, required this.secret});
@override
State<VerificationPage> createState() => _VerificationPageState();
}
class _VerificationPageState extends State<VerificationPage> {
String code = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Verify TOTP", style: TextStyle(color: Colors.white)),
centerTitle: true,
backgroundColor: Colors.green,
elevation: 0,
shadowColor: Colors.transparent,
),
body: Center(
child: ListView(
padding: const EdgeInsets.all(16.0),
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter TOTP Code',
),
onChanged: (value) {
setState(() {
code = value;
});
},
),
),
ElevatedButton(
onPressed: () {
setState(() {
if (AuthTOTP.verifyCode(secretKey: widget.secret, totpCode: code)) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Congratulations, TOTP is correct"),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(10),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10))),
));
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Opps, TOTP is incorrect"),
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(10),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10))),
));
}
});
},
child: const Text("Verify"),
),
],
),
),
);
}
}
以上示例展示了如何生成密钥、显示二维码、获取用户输入并验证TOTP代码。你可以根据需要调整和扩展这个示例。
更多关于Flutter一次性密码(TOTP)认证插件auth_totp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter一次性密码(TOTP)认证插件auth_totp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用auth_totp
插件来实现一次性密码(TOTP)认证的代码案例。这个插件允许你生成和验证基于时间的一次性密码(TOTP)。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加auth_totp
依赖:
dependencies:
flutter:
sdk: flutter
auth_totp: ^x.y.z # 请将x.y.z替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Dart文件中导入插件:
import 'package:auth_totp/auth_totp.dart';
3. 生成TOTP URI
要生成一个用于配置TOTP应用的URI,你需要提供密钥(通常是Base32编码的)、账户名(可选)、发行者名(可选)以及时间步长(默认为30秒)。
void generateTotpUri() {
String secret = 'JBSWY3DPEHPK3PXP'; // 示例密钥(Base32编码)
String accountName = 'user@example.com';
String issuer = 'MyApp';
int timeStep = 30; // 时间步长,单位秒
String uri = TOTP.generateTotpURI(
secret: secret,
issuer: issuer,
accountName: accountName,
timeStep: timeStep,
);
print('TOTP URI: $uri');
}
4. 生成和验证TOTP
使用生成的密钥,你可以生成当前时间的TOTP,并验证用户输入的TOTP是否正确。
void generateAndVerifyTotp() async {
String secret = 'JBSWY3DPEHPK3PXP'; // 示例密钥(Base32编码)
int timeStep = 30; // 时间步长,单位秒
int digits = 6; // TOTP长度,通常为6位
// 生成当前时间的TOTP
String generatedTotp = await TOTP.generateTotp(
secret: secret,
timeStep: timeStep,
digits: digits,
);
print('Generated TOTP: $generatedTotp');
// 用户输入的TOTP
String userInputTotp = '123456'; // 假设用户输入了这个TOTP
// 验证TOTP
bool isValid = await TOTP.verifyTotp(
secret: secret,
timeStep: timeStep,
digits: digits,
totp: userInputTotp,
window: 1, // 验证的时间窗口大小,允许前后偏差的时间步长数
);
print('Is TOTP valid? $isValid');
}
5. 完整示例
将上述代码整合到一个完整的示例中:
import 'package:flutter/material.dart';
import 'package:auth_totp/auth_totp.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('TOTP Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 生成TOTP URI
String secret = 'JBSWY3DPEHPK3PXP';
String accountName = 'user@example.com';
String issuer = 'MyApp';
int timeStep = 30;
String uri = TOTP.generateTotpURI(
secret: secret,
issuer: issuer,
accountName: accountName,
timeStep: timeStep,
);
print('TOTP URI: $uri');
// 生成和验证TOTP
String generatedTotp = await TOTP.generateTotp(
secret: secret,
timeStep: timeStep,
digits: 6,
);
print('Generated TOTP: $generatedTotp');
// 假设用户输入了这个TOTP
String userInputTotp = generatedTotp; // 在实际应用中,这将是用户输入的值
bool isValid = await TOTP.verifyTotp(
secret: secret,
timeStep: timeStep,
digits: 6,
totp: userInputTotp,
window: 1,
);
print('Is TOTP valid? $isValid');
// 显示结果(仅用于示例)
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('TOTP Valid: $isValid'),
),
);
},
child: Text('Generate and Verify TOTP'),
),
),
),
);
}
}
这个示例展示了如何在Flutter应用中生成TOTP URI、生成TOTP以及验证用户输入的TOTP。你可以根据实际需求进一步定制和扩展这个示例。