Flutter一次性密码(OTP)验证插件otp的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter一次性密码(OTP)验证插件otp的使用

简介

dart-otp 是一个用于生成RFC4226/RFC6238标准的一次性密码(OTP),包括基于时间的一次性密码(TOTP)和基于计数器的一次性密码(HOTP)。它支持Google Authenticator,并且提供了详细的API文档。

版本变更

在版本3.1.0中,dart-otp引入了重大行为变更,具体可以参考变更说明

安装

pubspec.yaml文件中添加依赖:

dependencies:
  otp: 3.1.2

然后在Dart代码中导入库:

import 'package:otp/otp.dart';

使用示例

示例代码

下面是一个完整的示例代码,演示如何使用dart-otp生成TOTP和HOTP:

import 'package:otp/otp.dart';
import 'package:timezone/data/latest.dart' as timezone;
import 'package:timezone/timezone.dart' as timezone;

void main() {
  // 初始化时区数据
  timezone.initializeTimeZones();

  // 获取当前时间
  final now = DateTime.now();
  
  // 设置为洛杉矶时区
  final pacificTimeZone = timezone.getLocation('America/Los_Angeles');
  final date = timezone.TZDateTime.from(now, pacificTimeZone);

  // 生成TOTP码,默认SHA1算法,适用于Google Authenticator
  final code = OTP.generateTOTPCodeString(
      'JBSWY3DPEHPK3PXP', date.millisecondsSinceEpoch,
      algorithm: Algorithm.SHA1, isGoogle: true);
  print('TOTP Code (SHA1, Google): $code');

  // 生成TOTP码,自定义刷新间隔为10秒
  final code2 = OTP.generateTOTPCodeString(
      'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch,
      interval: 10);
  print('TOTP Code (interval: 10 seconds): $code2');

  // 生成TOTP码,使用SHA512算法,自定义刷新间隔为20秒
  final code3 = OTP.generateTOTPCodeString(
      'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch,
      interval: 20, algorithm: Algorithm.SHA512);
  print('TOTP Code (SHA512, interval: 20 seconds): $code3');

  // 生成HOTP码
  final code4 =
      OTP.generateHOTPCodeString('OBRWE5CEFNFWQQJRMZRGM4LZMZIGKKZU', 1);
  print('HOTP Code: $code4');

  // 生成指定时间戳的TOTP码
  final code5 = OTP.generateTOTPCodeString('JBSWY3DPEHPK3PXP', 1362302550000);
  print('TOTP Code (specified timestamp): $code5');

  // 生成TOTP码,刷新间隔为60秒
  final code6 = OTP.generateTOTPCodeString(
      'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch,
      interval: 60);
  print('TOTP Code (interval: 60 seconds): $code6');
  print('Remaining seconds until next TOTP: ${OTP.remainingSeconds(interval: 60)}');

  // 生成默认设置的TOTP码
  final code7 = OTP.generateTOTPCodeString(
      'JBSWY3DPEHPK3PXP', DateTime.now().millisecondsSinceEpoch);
  print('Default TOTP Code: $code7');
  print('Remaining seconds until next TOTP: ${OTP.remainingSeconds()}');

  // 生成另一个TOTP码
  final code8 = OTP.generateTOTPCodeString('TULF5VNGGE267KF7BVZ3FGWBB7TELLIL',
      DateTime.now().millisecondsSinceEpoch);
  print('Another TOTP Code: $code8');
  print('Remaining seconds until next TOTP: ${OTP.remainingSeconds()}');

  // 尝试使用无效的密钥生成TOTP码(这将抛出异常)
  try {
    final code9 = OTP.generateTOTPCodeString(
        'sdfsdf', DateTime.now().millisecondsSinceEpoch,
        algorithm: Algorithm.SHA1);
    print('Invalid TOTP Code: $code9');
  } catch (e) {
    print('Error: $e');
  }
}

API说明

全局设置

  • useTOTPPaddingForHOTP:布尔值,默认为false。启用后,会使用TOTP的填充方法处理HOTP的密钥长度问题,但可能会导致与其他库的不兼容。

方法

  • OTP.generateTOTPCode(String secret, int currentTime, {int length: 6, int interval: 30, Algorithm algorithm: Algorithm.SHA256, bool isGoogle: false}):生成TOTP码,返回整数。
  • OTP.generateTOTPCodeString(String secret, int currentTime, {int length: 6, int interval: 30, Algorithm algorithm: Algorithm.SHA256, bool isGoogle: false}):生成TOTP码,返回字符串,保留前导零。
  • OTP.generateHOTPCode(String secret, int counter, {int length: 6}):生成HOTP码,返回整数。
  • OTP.generateHOTPCodeString(String secret, int counter, {int length: 6}):生成HOTP码,返回字符串,保留前导零。
  • OTP.constantTimeVerification(final String code, final String othercode):常量时间验证两个码是否相同,防止时间攻击。
  • OTP.remainingSeconds({int interval = 30}):返回剩余的秒数,基于上次调用生成TOTP码的时间。

通过以上内容,您可以快速上手dart-otp插件,实现一次性密码的生成与验证。希望这些信息对您有所帮助!


更多关于Flutter一次性密码(OTP)验证插件otp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter一次性密码(OTP)验证插件otp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,实现一次性密码(OTP)验证通常涉及到短信监听、OTP输入以及验证逻辑。虽然Flutter本身没有官方的OTP插件,但社区中有许多可用的插件可以帮助你实现这一功能。这里我将展示如何使用otp插件(假设你提到的otp是指某个具体的OTP插件,如果实际上是指其他插件如flutter_otp,请根据实际情况调整)来进行OTP验证。

首先,你需要在pubspec.yaml文件中添加依赖项。由于otp这个名称可能不太具体,我将以flutter_otp插件为例,因为它是一个流行的OTP处理库。

dependencies:
  flutter:
    sdk: flutter
  flutter_otp: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来获取依赖项。

接下来,展示一个如何使用flutter_otp插件的基本示例:

import 'package:flutter/material.dart';
import 'package:flutter_otp/flutter_otp.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: OTPScreen(),
    );
  }
}

class OTPScreen extends StatefulWidget {
  @override
  _OTPScreenState createState() => _OTPScreenState();
}

class _OTPScreenState extends State<OTPScreen> {
  final Otp otp = Otp();
  final TextEditingController _controller = TextEditingController();
  String _otpCode = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OTP Verification'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Enter OTP:', style: TextStyle(fontSize: 20)),
            SizedBox(height: 10),
            TextField(
              controller: _controller,
              maxLength: 6,
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'OTP',
              ),
              onChanged: (value) {
                setState(() {
                  _otpCode = value;
                });
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                if (_otpCode.length == 6) {
                  // 假设你有一个从服务器获取的OTP密钥和OTP长度
                  String secretKey = 'your_secret_key_here'; // 替换为你的密钥
                  int otpLength = 6;
                  
                  // 生成本地OTP用于比较(通常这一步在服务器端完成)
                  String generatedOTP = otp.generateOTP(secretKey, otpLength);

                  // 在实际应用中,你应该将用户输入的OTP发送到服务器进行验证
                  // 这里我们仅做本地比较演示
                  if (_otpCode == generatedOTP) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('OTP Verified!')),
                    );
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Invalid OTP')),
                    );
                  }
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Please enter a 6-digit OTP')),
                  );
                }
              },
              child: Text('Verify OTP'),
            ),
          ],
        ),
      ),
    );
  }
}

注意

  1. 在实际应用中,你应该将用户输入的OTP发送到服务器进行验证,而不是在客户端生成并比较OTP。客户端生成的OTP仅用于演示目的。
  2. 密钥(secretKey)通常是由服务器生成的,并且应该安全地存储。
  3. flutter_otp插件提供了生成OTP的功能,但验证通常是由服务器端完成的,因为它涉及到安全性和准确性。

如果你使用的是另一个名为otp的插件,请参考该插件的文档进行相应的调整。大多数OTP插件的基本用法是相似的,主要区别在于API的细节。

回到顶部