Flutter一次性密码(OTP)生成与验证插件app_otp的使用

Flutter一次性密码(OTP)生成与验证插件app_otp的使用

使用

import 'package:app_otp/app_otp.dart';

AppOTPTextField _buildOTPWidget() {
    return AppOTPTextField(
        onCompleted: (otp) {
            setState(() {
            _otpCompleted = otp;
            });
        },
        onChanged: (otp) {
            setState(() {
            _otp = otp;
            });
        },
    );
}

示例代码

示例代码文件:main.dart

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

void main() {
  runApp(
    const MainApp(),
  );
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  [@override](/user/override)
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(
        builder: (context) {
          return Container(
            color: Colors.white,
            child: Center(
              child: TextButton(
                child: const Text('Navigate To OTP'),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const Home(),
                    ),
                  );
                },
              ),
            ),
          );
        }
      ),
    );
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  [@override](/user/override)
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String? _otp;
  String? _otpCompleted;
  bool _enable = true;
  AppOTPTextFieldController? _controller;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('APP OTP 示例'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 24,
                ),
                child: AppOTPTextField(
                  boxHeight: 48,
                  boxWidth: 40,
                  enabled: _enable,
                  onAppOTPTextFieldCreated: (controller) {
                    _controller = controller;
                  },
                  onCompleted: (otp) {
                    setState(() {
                      _otpCompleted = otp;
                    });
                  },
                  onChanged: (otp) {
                    setState(() {
                      _otp = otp;
                    });
                  },
                ),
              ),
              const SizedBox(
                height: 24,
              ),
              ElevatedButton(
                onPressed: () {
                  _controller?.clear();
                },
                child: const Text('清除'),
              ),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                  backgroundColor: _enable ? Colors.red : Colors.blue,
                ),
                onPressed: () {
                  setState(() {
                    _enable = !_enable;
                  });
                },
                child: Text(_enable ? '禁用' : '启用'),
              ),
              const SizedBox(
                height: 24,
              ),
              Text('启用状态: $_enable'),
              _otpCompleted != null
                  ? Text(
                '完成回调: $_otpCompleted',
              )
                  : const SizedBox(),
              _otp != null
                  ? Text(
                '输入改变回调: $_otp',
              )
                  : const SizedBox(),
            ],
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


app_otp 是一个用于在 Flutter 应用中生成和验证一次性密码(OTP)的插件。它基于时间的一次性密码(TOTP)和基于计数器的一次性密码(HOTP)算法,可以用于实现双因素认证(2FA)等功能。

以下是使用 app_otp 插件生成和验证 OTP 的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 app_otp 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  app_otp: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 导入插件

在需要使用 OTP 功能的 Dart 文件中导入 app_otp 插件:

import 'package:app_otp/app_otp.dart';

3. 生成 OTP

使用 AppOtp.generateTOTP 方法生成基于时间的 OTP(TOTP)。你需要提供一个共享密钥和时间戳。

void generateOTP() {
  String secretKey = "JBSWY3DPEHPK3PXP"; // 示例密钥
  int timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000; // 当前时间戳(秒)

  String otp = AppOtp.generateTOTP(secretKey, timestamp);
  print("Generated OTP: $otp");
}

4. 验证 OTP

使用 AppOtp.verifyTOTP 方法验证用户输入的 OTP 是否正确。

void verifyOTP(String userInput) {
  String secretKey = "JBSWY3DPEHPK3PXP"; // 示例密钥
  int timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000; // 当前时间戳(秒)

  bool isValid = AppOtp.verifyTOTP(secretKey, timestamp, userInput);
  if (isValid) {
    print("OTP is valid");
  } else {
    print("OTP is invalid");
  }
}

5. 使用基于计数器的 OTP(HOTP)

如果你需要使用基于计数器的 OTP(HOTP),可以使用 AppOtp.generateHOTPAppOtp.verifyHOTP 方法。

void generateHOTP() {
  String secretKey = "JBSWY3DPEHPK3PXP"; // 示例密钥
  int counter = 123456; // 计数器值

  String hotp = AppOtp.generateHOTP(secretKey, counter);
  print("Generated HOTP: $hotp");
}

void verifyHOTP(String userInput) {
  String secretKey = "JBSWY3DPEHPK3PXP"; // 示例密钥
  int counter = 123456; // 计数器值

  bool isValid = AppOtp.verifyHOTP(secretKey, counter, userInput);
  if (isValid) {
    print("HOTP is valid");
  } else {
    print("HOTP is invalid");
  }
}

6. 示例应用

以下是一个完整的示例应用,展示了如何生成和验证 OTP:

import 'package:flutter/material.dart';
import 'package:app_otp/app_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> {
  String generatedOTP = "";

  void generateOTP() {
    String secretKey = "JBSWY3DPEHPK3PXP";
    int timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;

    setState(() {
      generatedOTP = AppOtp.generateTOTP(secretKey, timestamp);
    });
  }

  void verifyOTP(String userInput) {
    String secretKey = "JBSWY3DPEHPK3PXP";
    int timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;

    bool isValid = AppOtp.verifyTOTP(secretKey, timestamp, userInput);
    if (isValid) {
      print("OTP is valid");
    } else {
      print("OTP is invalid");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("OTP Demo"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("Generated OTP: $generatedOTP"),
            ElevatedButton(
              onPressed: generateOTP,
              child: Text("Generate OTP"),
            ),
            TextField(
              decoration: InputDecoration(labelText: "Enter OTP"),
              onChanged: (value) {
                verifyOTP(value);
              },
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部