Flutter电话号码验证插件twilio_phone_verify的使用

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

Flutter电话号码验证插件twilio_phone_verify的使用

twilio_phone_verify 是一个用于通过 Twilio 验证电话号码和电子邮件地址的 Flutter 插件。

使用方法

添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  twilio_phone_verify:

初始化插件

创建并初始化一个新的 TwilioPhoneVerify 对象,替换相应的 SID 和 Token:

TwilioPhoneVerify _twilioPhoneVerify = TwilioPhoneVerify(
    accountSid: 'your_account_sid', // 替换为您的 Account SID
    authToken: 'your_auth_token',   // 替换为您的 Auth Token
    serviceSid: 'your_service_sid'  // 替换为您的 Service SID
);

电话号码验证

发送验证码到手机

发送验证码到指定的手机号码:

var twilioResponse = await _twilioPhoneVerify.sendSmsCode('phone_number');

if (twilioResponse.successful) {
    // 验证码已发送
} else {
    print(twilioResponse.errorMessage);
}

验证验证码

验证用户输入的验证码是否正确:

var twilioResponse = await _twilioPhoneVerify.verifySmsCode(
    phone: 'phone_number', 
    code: 'user_entered_code'
);

if (twilioResponse.successful) {
    if (twilioResponse.verification.status == VerificationStatus.approved) {
        print('Phone number is approved');
    } else {
        print('Invalid code');
    }
} else {
    print(twilioResponse.errorMessage);
}

完整示例 Demo

以下是一个完整的 Flutter 应用程序示例,演示如何使用 twilio_phone_verify 插件进行电话号码验证:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Twilio Phone Verify',
      theme: ThemeData(
        primaryColor: Color(0xFF233659),
      ),
      home: PhoneVerification(),
    );
  }
}

enum VerificationState { enterPhone, enterSmsCode }

class PhoneVerification extends StatefulWidget {
  @override
  _PhoneVerificationState createState() => _PhoneVerificationState();
}

class _PhoneVerificationState extends State<PhoneVerification> {
  TwilioPhoneVerify _twilioPhoneVerify;

  var verificationState = VerificationState.enterPhone;
  var phoneNumberController = TextEditingController();
  var smsCodeController = TextEditingController();
  bool loading = false;
  String errorMessage;
  String successMessage;

  @override
  void initState() {
    super.initState();
    _twilioPhoneVerify = TwilioPhoneVerify(
        accountSid: 'your_account_sid',
        serviceSid: 'your_service_sid',
        authToken: 'your_auth_token');
  }

  @override
  Widget build(BuildContext context) {
    return verificationState == VerificationState.enterPhone
        ? _buildEnterPhoneNumber()
        : _buildEnterSmsCode();
  }

  void changeErrorMessage(var message) => setState(() => errorMessage = message);

  void changeSuccessMessage(var message) => setState(() => successMessage = message);

  void changeLoading(bool status) => setState(() => loading = status);

  void switchToSmsCode() async {
    changeSuccessMessage(null);
    changeErrorMessage(null);
    changeLoading(false);
    setState(() {
      verificationState = VerificationState.enterSmsCode;
    });
  }

  void switchToPhoneNumber() {
    if (loading) return;
    changeSuccessMessage(null);
    changeErrorMessage(null);
    setState(() {
      verificationState = VerificationState.enterPhone;
    });
  }

  void sendCode() async {
    if (phoneNumberController.text.isEmpty || loading) return;
    changeLoading(true);
    TwilioResponse twilioResponse =
        await _twilioPhoneVerify.sendSmsCode(phoneNumberController.text);

    if (twilioResponse.successful) {
      changeSuccessMessage('Code sent to ${phoneNumberController.text}');
      await Future.delayed(Duration(seconds: 1));
      switchToSmsCode();
    } else {
      changeErrorMessage(twilioResponse.errorMessage);
    }
    changeLoading(false);
  }

  void verifyCode() async {
    if (phoneNumberController.text.isEmpty ||
        smsCodeController.text.isEmpty ||
        loading) return;
    changeLoading(true);
    TwilioResponse twilioResponse = await _twilioPhoneVerify.verifySmsCode(
        phone: phoneNumberController.text, code: smsCodeController.text);
    if (twilioResponse.successful) {
      if (twilioResponse.verification.status == VerificationStatus.approved) {
        changeSuccessMessage('Phone number is approved');
      } else {
        changeSuccessMessage('Invalid code');
      }
    } else {
      changeErrorMessage(twilioResponse.errorMessage);
    }
    changeLoading(false);
  }

  Widget _buildEnterPhoneNumber() {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(40.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: phoneNumberController,
              keyboardType: TextInputType.phone,
              decoration: InputDecoration(labelText: 'Enter Phone Number'),
            ),
            SizedBox(height: 20),
            Container(
              width: double.infinity,
              height: 40,
              child: TextButton(
                  onPressed: sendCode,
                  style: TextButton.styleFrom(
                      backgroundColor: Theme.of(context).primaryColor),
                  child: loading
                      ? _loader()
                      : Text(
                          'Send code',
                          style: TextStyle(color: Colors.white),
                        )),
            ),
            if (errorMessage != null) ...[
              SizedBox(height: 30),
              _errorWidget()
            ],
            if (successMessage != null) ...[
              SizedBox(height: 30),
              _successWidget()
            ]
          ],
        ),
      ),
    );
  }

  Widget _buildEnterSmsCode() {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.transparent,
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios, size: 18, color: Theme.of(context).primaryColor),
          onPressed: switchToPhoneNumber,
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(40.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: smsCodeController,
              keyboardType: TextInputType.number,
              decoration: InputDecoration(labelText: 'Enter Sms Code'),
            ),
            SizedBox(height: 20),
            Container(
              width: double.infinity,
              height: 40,
              child: TextButton(
                  onPressed: verifyCode,
                  style: TextButton.styleFrom(
                      backgroundColor: Theme.of(context).primaryColor),
                  child: loading
                      ? _loader()
                      : Text(
                          'Verify',
                          style: TextStyle(color: Colors.white),
                        )),
            ),
            if (errorMessage != null) ...[
              SizedBox(height: 30),
              _errorWidget()
            ],
            if (successMessage != null) ...[
              SizedBox(height: 30),
              _successWidget()
            ]
          ],
        ),
      ),
    );
  }

  Widget _loader() => SizedBox(
        height: 15,
        width: 15,
        child: CircularProgressIndicator(strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white)),
      );

  Widget _errorWidget() => Material(
        borderRadius: BorderRadius.circular(5),
        color: Colors.red.withOpacity(.1),
        child: Padding(
          padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
          child: Row(
            children: [
              Expanded(child: Text(errorMessage, style: TextStyle(color: Colors.red))),
              IconButton(icon: Icon(Icons.close, size: 16), onPressed: () => changeErrorMessage(null))
            ],
          ),
        ),
      );

  Widget _successWidget() => Material(
        borderRadius: BorderRadius.circular(5),
        color: Colors.green.withOpacity(.1),
        child: Padding(
          padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
          child: Row(
            children: [
              Expanded(child: Text(successMessage, style: TextStyle(color: Colors.green))),
              IconButton(icon: Icon(Icons.close, size: 16), onPressed: () => changeSuccessMessage(null))
            ],
          ),
        ),
      );
}

以上示例展示了如何在 Flutter 应用中集成 Twilio 的电话号码验证功能。确保替换所有占位符(如 your_account_sid, your_auth_token, your_service_sid)为您实际的 Twilio 凭据。


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

1 回复

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


当然,以下是如何在Flutter项目中使用twilio_phone_verify插件进行电话号码验证的示例代码。这个插件允许你集成Twilio的Phone Verify API,用于电话号码验证。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加twilio_phone_verify依赖:

dependencies:
  flutter:
    sdk: flutter
  twilio_phone_verify: ^latest_version  # 请替换为最新版本号

2. 导入插件

在你的Dart文件中导入twilio_phone_verify插件:

import 'package:twilio_phone_verify/twilio_phone_verify.dart';

3. 初始化插件和配置

你需要在应用的初始化阶段配置Twilio的Account SID和Auth Token。确保这些敏感信息不会硬编码在客户端代码中,而是从安全的后端服务获取。

void initTwilio() async {
  TwilioPhoneVerify.init(
    accountSid: 'your_account_sid',  // 从Twilio控制台获取
    authToken: 'your_auth_token'     // 从Twilio控制台获取
  );
}

4. 发起电话号码验证请求

在你的UI中,当用户输入电话号码后,调用以下方法来发起验证请求:

void verifyPhoneNumber(String phoneNumber) async {
  try {
    String accessToken = await TwilioPhoneVerify.createAccessToken(phoneNumber);
    // 通常,你会将accessToken发送到你的服务器,由服务器完成后续的验证流程
    // 这里我们假设服务器返回了一个verificationSid
    String verificationSid = await sendVerificationRequestToServer(accessToken);

    // 监听验证状态变化
    TwilioPhoneVerify.verificationStatusStream.listen((status) {
      if (status != null) {
        if (status.isVerified) {
          print('Phone number is verified!');
        } else if (status.isPending) {
          print('Verification code is pending...');
        } else if (status.isFailed) {
          print('Verification failed: ${status.error}');
        }
      }
    });

    // 你可以让用户输入收到的验证码来手动验证
    // TwilioPhoneVerify.verifyCode(phoneNumber, userEnteredCode);

  } catch (e) {
    print('Error during phone number verification: $e');
  }
}

// 这是一个模拟函数,你需要根据你的后端API来实现
Future<String> sendVerificationRequestToServer(String accessToken) async {
  // 发送accessToken到你的服务器,并处理服务器响应
  // 这里返回的是从服务器获取的verificationSid
  // 示例代码(实际实现需根据你的后端API调整):
  // String response = await httpPost('your_server_endpoint', {'accessToken': accessToken});
  // return parseVerificationSidFromResponse(response);
  
  // 返回模拟的verificationSid
  return 'VZ123456789abcdef01234567890abcdef';
}

5. 监听和处理验证状态

如上所示,你可以通过监听verificationStatusStream来处理验证状态的变化。当用户输入验证码时,你也可以手动调用verifyCode方法进行验证。

6. 完整示例

以下是一个完整的示例,包括UI部分,用于演示如何集成和使用twilio_phone_verify插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Twilio Phone Verify Example'),
        ),
        body: PhoneVerificationScreen(),
      ),
    );
  }
}

class PhoneVerificationScreen extends StatefulWidget {
  @override
  _PhoneVerificationScreenState createState() => _PhoneVerificationScreenState();
}

class _PhoneVerificationScreenState extends State<PhoneVerificationScreen> {
  final TextEditingController _phoneController = TextEditingController();
  final TextEditingController _codeController = TextEditingController();
  String _verificationMessage = '';

  @override
  void initState() {
    super.initState();
    initTwilio();
  }

  void initTwilio() async {
    TwilioPhoneVerify.init(
      accountSid: 'your_account_sid',
      authToken: 'your_auth_token'
    );

    TwilioPhoneVerify.verificationStatusStream.listen((status) {
      setState(() {
        if (status != null) {
          if (status.isVerified) {
            _verificationMessage = 'Phone number is verified!';
          } else if (status.isPending) {
            _verificationMessage = 'Verification code is pending...';
          } else if (status.isFailed) {
            _verificationMessage = 'Verification failed: ${status.error}';
          }
        }
      });
    });
  }

  void _verifyPhoneNumber() async {
    String phoneNumber = _phoneController.text;
    await verifyPhoneNumber(phoneNumber);
  }

  void _verifyCode() async {
    String phoneNumber = _phoneController.text;
    String code = _codeController.text;
    await TwilioPhoneVerify.verifyCode(phoneNumber, code);
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextField(
            controller: _phoneController,
            decoration: InputDecoration(labelText: 'Phone Number'),
            keyboardType: TextInputType.phone,
          ),
          SizedBox(height: 16),
          ElevatedButton(
            onPressed: _verifyPhoneNumber,
            child: Text('Verify Phone Number'),
          ),
          SizedBox(height: 16),
          TextField(
            controller: _codeController,
            decoration: InputDecoration(labelText: 'Verification Code'),
            keyboardType: TextInputType.number,
          ),
          SizedBox(height: 16),
          ElevatedButton(
            onPressed: _verifyCode,
            child: Text('Verify Code'),
          ),
          SizedBox(height: 16),
          Text(_verificationMessage),
        ],
      ),
    );
  }
}

注意事项

  1. 安全性:不要在客户端代码中硬编码Twilio的Account SID和Auth Token。这些敏感信息应该从安全的后端服务获取。
  2. 后端集成:上述示例中的sendVerificationRequestToServer函数是一个模拟函数,你需要根据你的后端API来实现实际的请求和响应处理。
  3. 用户隐私:确保你遵守相关的隐私法规和用户协议,特别是在处理用户的电话号码时。

希望这个示例能帮助你在Flutter项目中成功集成和使用twilio_phone_verify插件进行电话号码验证。

回到顶部