Flutter身份验证插件verify的使用

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

Flutter身份验证插件verify的使用

verify 是一个用于Dart和Flutter项目的函数式编程风格的验证DSL。它允许你创建灵活且可扩展的验证器,适用于各种场景如表单验证、数据解析等。以下是关于如何使用 verify 插件的详细说明和示例。

功能特性

  • 完全可扩展:你可以创建自己的组合器、验证器原语等。
  • 灵活:基于扩展的API,没有单一类创建,所有都是纯函数。
  • 可定制:可以定义自己的错误类型,按需组织验证器。
  • BLoC友好:参见示例实现。
  • 空安全:作为预发布版本支持。

使用方法

创建验证器

验证器是一个简单的函数别名:

// 根据是否将验证的主题转换为另一种类型,有两种变体
typedef ValidatorT<S, T> = Either<List<dynamic>, T> Function(S subject);
typedef Validator<S> = Either<List<dynamic>, S> Function(S subject);

例如,创建一个简单的电子邮件验证器:

final Validator<String> emailValidator = (String email) {
  return email.contains('@') ? Right(email) : Left(['Bad email format']);
};

简单验证器从谓词创建

使用内置的帮助函数:

final containsAt = Verify.that(
  (String email) => email.contains('@'),
  error: 'Bad email format'
);

复用验证器

通过组合构建更复杂的验证器:

final Validator<String> emailValidator = Verify.all([containsAt, notEmpty]);

验证并转换

验证器也可以转换其输入,例如同时进行解析和验证:

final Validator<String, int> intParsingValidator = (String str) => Right(int.parse(str));

final validator = intParsingValidator.onException((_) => Error('not an integer'));

字段验证

给定一个模型,例如用户:

class User extends Equatable {
  final String? phone;
  final String? mail;
  final int? age;

  const User(this.phone, this.mail, this.age);

  [@override](/user/override)
  List<Object> get props => [phone ?? '', mail ?? '', age ?? ''];
}

可以通过链式调用 checkcheckField 方法对对象及其字段进行额外检查:

final userValidator = Verify.empty<User>()
    .check((user) => !user.phone!.isEmpty, error: Error('phone empty'))
    .checkField((user) => user.mail!, emailValidator);

final someUser = User('', '', 25);
final Either<List<Error>, User> validationResult = userValidator.verify(someUser);

运行验证器

运行验证器只需传递参数,因为它是函数。为了更优雅地处理,提供了一个 verify 方法,该方法不仅可以转发参数到调用的验证器,还可以过滤错误列表并将其转换为特定错误类型:

final signUpValidation = Verify.subject<SignUpState>();
final errors = signUpValidation
    .verify<SignUpError>(newState); // Either<List<SignUpError>, SignUpState>

内置验证器

虽然 verify 不自带很多内置验证器,但它们非常容易创建。它确实带有一些正则表达式的简写:

final validator = Verify.fromRegex(RegExp(r"(^\d+$)", error: Error('not just digits'))); // Validator<String, int>

表单验证

通常情况下,你会建模你的错误类型类似于以下形式:

enum FormField {
  email,
  password,
  passwordConfirmation,
}

class SignUpError extends ValidationError {
  final String message;
  final FormField field;

  SignUpError(this.message, {required this.field});

  [@override](/user/override)
  String get errorDescription => message;
}

在这种情况下,方便的是能够按字段分组错误:

final validator = Verify.inOrder<SignUpFormState>([
  validateMail,
  validatePassword,
  validateConfirmation,
]);

final Map<FormField, SignUpError> errorMap = validator
    .verify<SignUpError>(someState)
    .errorsGroupedBy((error) => error.field);

示例代码

下面是一个完整的Flutter应用示例,展示了如何在实际项目中使用 verify 插件:

import 'package:flutter/material.dart';
import 'package:verify_example/pages/signup_page.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: SignUpPage(),
    );
  }
}

class SignUpPage extends StatefulWidget {
  [@override](/user/override)
  _SignUpPageState createState() => _SignUpPageState();
}

class _SignUpPageState extends State<SignUpPage> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  String _errorMessage = '';

  void _validateAndSubmit() {
    final email = _emailController.text;
    final password = _passwordController.text;

    final emailValidator = Verify.that(
      (String email) => email.contains('@'),
      error: 'Invalid email format',
    );

    final passwordValidator = Verify.that(
      (String password) => password.length >= 6,
      error: 'Password must be at least 6 characters long',
    );

    final combinedValidator = Verify.all([emailValidator, passwordValidator]);

    final result = combinedValidator.verify(email).merge(combinedValidator.verify(password));

    setState(() {
      if (result.isLeft()) {
        _errorMessage = result.fold((errors) => errors.join(', '), (_) => '');
      } else {
        _errorMessage = 'Success!';
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sign Up'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _validateAndSubmit,
              child: Text('Sign Up'),
            ),
            SizedBox(height: 20),
            Text(_errorMessage, style: TextStyle(color: Colors.red)),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter身份验证插件verify的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter身份验证插件verify的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用verify插件进行身份验证的代码示例。需要注意的是,verify插件的具体实现和功能可能会依赖于具体的身份验证服务(如Google身份验证器、短信验证等),这里我们假设你指的是一个常见的基于OTP(一次性密码)的身份验证流程。

首先,确保你已经在pubspec.yaml文件中添加了必要的依赖项。例如,如果你使用的是flutter_otp插件来生成和验证OTP,你可以添加如下依赖:

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

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

接下来是一个基本的Flutter应用示例,它展示了如何使用OTP进行身份验证。

main.dart

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(
      title: 'Flutter OTP Verification',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: OTPVerificationScreen(),
    );
  }
}

class OTPVerificationScreen extends StatefulWidget {
  @override
  _OTPVerificationScreenState createState() => _OTPVerificationScreenState();
}

class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
  final Otp otp = Otp();
  String secret = otp.generateSecret();
  String otpCode = '';
  bool isVerified = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OTP Verification'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Secret Key: $secret'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                String generatedOtp = await otp.generateOtp(secret: secret);
                // 这里通常会将生成的OTP发送到用户的设备(如短信、邮件等)
                // 但为了演示,我们直接在UI上显示它
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Generated OTP: $generatedOtp')),
                );
              },
              child: Text('Generate OTP'),
            ),
            SizedBox(height: 20),
            TextField(
              decoration: InputDecoration(labelText: 'Enter OTP'),
              keyboardType: TextInputType.number,
              onChanged: (value) {
                otpCode = value;
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                bool result = await otp.verifyOtp(
                  secret: secret,
                  otp: otpCode,
                );
                setState(() {
                  isVerified = result;
                });
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('OTP Verified: $isVerified')),
                );
              },
              child: Text('Verify OTP'),
            ),
          ],
        ),
      ),
    );
  }
}

说明

  1. 生成密钥:使用otp.generateSecret()生成一个用于生成和验证OTP的秘密密钥。
  2. 生成OTP:使用otp.generateOtp(secret: secret)根据秘密密钥生成一个6位数的OTP。在实际应用中,这个OTP会发送到用户的设备(如通过短信或电子邮件)。
  3. 验证OTP:用户输入收到的OTP后,使用otp.verifyOtp(secret: secret, otp: otpCode)来验证输入的OTP是否正确。

请注意,flutter_otp插件的具体API和实现可能会有所不同,上述代码是基于假设的API设计的。如果verify插件是指另一个特定的身份验证插件,请查阅该插件的官方文档以获取准确的API和用法。

回到顶部