Flutter身份验证插件arcana_auth的使用

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

Flutter身份验证插件arcana_auth的使用

Arcana Auth Flutter SDK

移动应用程序可以通过集成Arcana Auth Flutter SDK轻松地引导用户并允许已认证的用户签署区块链交易。Arcana Auth为Web3操作启用了标准的以太坊提供者

通过Arcana Auth,用户无需下载钱包扩展或管理密钥即可开始与任何区块链交互。一旦经过认证,Arcana钱包将在应用的上下文中立即对用户可用。

开发者可以使用即插即用的用户认证功能,通过内置登录UI进行用户引导,或者创建自定义UI来引导用户。可以使用Arcana仪表板配置一个或多个认证机制来引导用户。在集成之前,开发者必须使用Arcana开发者仪表板注册应用并获得唯一的客户端ID。

支持以下认证机制:

  • 社交登录

    • Discord
    • GitHub
    • Google
    • Steam(即将推出!)
    • Twitter
    • Twitch
  • 无密码、基于OTP的认证

  • 自定义IAM

    • Cognito
    • Firebase(即将推出!)

使用SDK

按照以下步骤配置并集成Arcana Auth Flutter SDK到任何使用Flutter的移动应用中:

步骤1:配置认证

在安装和集成Arcana Auth Flutter SDK之前,首先需要为Flutter应用获取一个客户端ID。使用Arcana开发者仪表板并注册应用到Arcana网络。每个注册的应用都会分配一个唯一的客户端ID。详情见’如何配置认证SDK’文档。

步骤2:安装

Arcana Auth Flutter SDK作为Flutter插件包在Pub.dev上可用。

在你的应用的pubspec.yaml文件的依赖部分添加以下行:

  arcana_auth_flutter: ^0.0.7 

步骤3:将认证集成到应用中

作为将Flutter应用与认证SDK集成的一部分,当创建AuthProvider时指定上一步中分配的唯一客户端ID

import 'package:arcana_sdk/arcana_sdk.dart';

final auth = AuthProvider(clientId:"xar_xxxx_...");
auth.init(context: context);

初始化后,你可以调用AuthProvider函数来进行用户引导和签署区块链交易。

认证SDK功能

登录/登出

使用社交登录

通过调用loginWithSocial并传递适当的提供者字符串,可以使用社交提供者(如Google)来引导用户。

auth.loginWithSocial("google").then((_) => {
  // 登录成功
}).catchError(...);
使用OTP登录

通过OTP方式,无需电子邮件即可引导用户登录到Flutter应用:

auth.loginWithOTP("${email_id}").then((_) => {
  // 登录成功
}).catchError(...);
登出
auth.logout().then((_) => {
  // 登出
});

显示/隐藏钱包

一旦用户经过认证,他们可以访问Arcana钱包并签署区块链交易。Flutter应用可以使用以下函数控制Arcana钱包的显示:

auth.showWallet();
auth.hideWallet();

要确定在Flutter应用中Arcana钱包是否在应用的上下文中可见,获取可见性状态:

var isVisible = auth.isVisible();

Flutter应用可以清除Webview缓存:

auth.clearCache();

Web3操作

AuthProvider支持JSON-RPC请求进行Web3操作:

EIP-1193请求
auth.request(method: "...", params: [...]).then(() => ...);
获取登录用户的详细信息
auth.getUserInfo().then((UserInfo info) => ...);
发起发送交易请求
auth.sendTransaction({ to: "", value: "" }).then((hash) => ...);
获取用户账户地址
auth.getAccount().then((account) => ...);

文档

查看Arcana网络文档中的Flutter应用快速入门指南、Arcana钱包用户指南以及Arcana开发者仪表板用户指南

支持

对于任何支持或集成相关的查询,请联系Arcana支持团队

贡献

我们欢迎社区对Arcana Auth SDK的所有贡献。阅读我们的贡献指南以了解SDK开发过程、如何提出错误修复和改进以及我们期望参与者遵守的行为准则。请参阅本README的构建和测试部分以了解如何在提交贡献之前测试和验证您的更改。

许可证

Arcana Auth SDK在MIT许可证下分发。

详情见Arcana许可证


示例代码

以下是完整的示例代码:

import 'package:arcana_sdk_example/strings.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:arcana_auth/arcana_sdk.dart';

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final auth = AuthProvider(
      clientId: "xar_dev_c48c5ca3ae8fff43289949cc5bdf9ed1af8ca102");
  TextEditingController heightController = TextEditingController();
  TextEditingController widthController = TextEditingController();
  String logs = '';
  String action = '';

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  // 平台消息是异步的,因此我们在异步方法中初始化。
  Future<void> initPlatformState() async {
    setState(() {
      logs = '';
    });
    auth.init(context: context);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Column(
          children: [
            Row(children: [
              Flexible(
                child: Container(
                  padding: const EdgeInsets.only(
                      bottom: 13.0, top: 13.0, left: 13.0, right: 13.0),
                  child: Text(
                    "结果: $logs",
                    style: const TextStyle(
                      fontSize: 13.0,
                      fontFamily: 'Roboto',
                      color: Color(0xFF212121),
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
            ]),
            Row(children: [
              Container(
                  padding: const EdgeInsets.only(
                      bottom: 13.0, top: 13.0, left: 13.0, right: 13.0),
                  width: MediaQuery.of(context).size.width * 0.8,
                child: Row(children: [Flexible(
                  child: Text(
                    "操作: $action",
                    style: const TextStyle(
                      fontSize: 13.0,
                      fontFamily: 'Roboto',
                      color: Color(0xFF212121),
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                )],
                ),
              ),
            ]),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                      onPressed: () {
                        auth.loginWithSocial("google").then((_) {
                          action = "login_complete";
                          setState(() {});
                        });
                        logs = '';
                        action = 'login_google';
                        setState(() {});
                      },
                      child: const Text("使用Google登录")),
                )
              ],
            ),
            Row(
              children: [
                Expanded(
                    child: ElevatedButton(
                        onPressed: () {
                          auth.showWallet();
                          logs = '';
                          action = 'show_wallet';
                          setState(() {});
                        },
                        child: Text("显示"))),
                const SizedBox(width: 50),
                Expanded(
                    child: ElevatedButton(
                        onPressed: () {
                          auth.hideWallet();
                          action = 'hide_wallet';
                        },
                        child: Text("隐藏")),
              ),
            ),
            Row(children: [
              Expanded(
                child: ElevatedButton(
                    onPressed: () {
                      auth.getUserInfo().then((info) {
                        debugPrint(info.address);
                        logs = info.toJSONString();
                        action = 'get_user_info';
                        setState(() {});
                      });
                    },
                    child: const Text('获取用户信息')),
              ),
              const SizedBox(width: 50),
              Expanded(
                child: ElevatedButton(
                    onPressed: () {
                      auth.sendTransaction(params: {
                        "to": "0xE28F01Cf69f27Ee17e552bFDFB7ff301ca07e780",
                        "value": "0x9184e72a"
                      }).then((hash) {
                        debugPrint("hash: $hash");
                        logs = hash;
                        action = 'send_transaction';
                        setState(() {});
                      });
                    },
                    child: const Text('发送交易')),
              )
            ]),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                      onPressed: () {
                        auth.getAccount().then((account) {
                          debugPrint("account: $account");
                          logs = account;
                          action = 'get_account';
                          setState(() {});
                        });
                      },
                      child: const Text('获取账户')),
                ),
                const SizedBox(width: 50),
                Expanded(
                  child: ElevatedButton(
                      onPressed: () {
                        auth.logout();
                        action = 'logout';
                      },
                      child: const Text('登出')),
                ),
              ],
            ),
            Row(
              children: [
                Expanded(
                    child: TextField(
                  controller: heightController,
                )),
                Expanded(
                    child: TextField(
                  controller: widthController,
                )),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用arcana_auth插件进行身份验证的示例代码。arcana_auth是一个用于处理身份验证流程的Flutter插件,通常用于集成第三方身份验证服务。不过,请注意,由于arcana_auth并非一个广泛知名的插件(在撰写时),以下示例将基于一个假设的身份验证流程,因为具体的实现细节可能会根据实际插件的API有所不同。

首先,确保在pubspec.yaml文件中添加arcana_auth依赖(假设该插件存在并可用):

dependencies:
  flutter:
    sdk: flutter
  arcana_auth: ^x.y.z  # 替换为实际版本号

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

接下来,以下是一个如何在Flutter应用中使用arcana_auth进行身份验证的示例代码:

import 'package:flutter/material.dart';
import 'package:arcana_auth/arcana_auth.dart';  // 假设的包导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Arcana Auth Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AuthScreen(),
    );
  }
}

class AuthScreen extends StatefulWidget {
  @override
  _AuthScreenState createState() => _AuthScreenState();
}

class _AuthScreenState extends State<AuthScreen> {
  final ArcanaAuth _auth = ArcanaAuth();
  String _userStatus = "Not Logged In";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Arcana Auth Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'User Status: $_userStatus',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                try {
                  // 假设有一个方法用于启动第三方身份验证流程
                  var result = await _auth.startAuthFlow();
                  if (result != null && result.isSuccessful) {
                    setState(() {
                      _userStatus = "Logged In as ${result.user.displayName}";
                    });
                  } else {
                    setState(() {
                      _userStatus = "Authentication Failed";
                    });
                  }
                } catch (e) {
                  setState(() {
                    _userStatus = "Error: ${e.message}";
                  });
                }
              },
              child: Text('Login'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                try {
                  // 假设有一个方法用于登出
                  await _auth.logout();
                  setState(() {
                    _userStatus = "Not Logged In";
                  });
                } catch (e) {
                  setState(() {
                    _userStatus = "Logout Error: ${e.message}";
                  });
                }
              },
              child: Text('Logout'),
            ),
          ],
        ),
      ),
    );
  }
}

// 假设的 ArcanaAuth 类定义(实际使用时请参考插件文档)
class ArcanaAuth {
  Future<AuthResult?> startAuthFlow() async {
    // 这里应该是启动第三方身份验证流程的代码
    // 例如,打开一个网页视图让用户登录,然后返回结果
    // 由于这是一个示例,这里只是返回一个模拟结果
    return Future.delayed(Duration(seconds: 2), () {
      return AuthResult(isSuccessful: true, user: User(displayName: "Test User"));
    });
  }

  Future<void> logout() async {
    // 这里应该是登出逻辑的代码
    // 例如,清除存储的令牌或用户信息
    // 由于这是一个示例,这里只是模拟登出操作
    return Future.delayed(Duration(seconds: 1), () {});
  }
}

// 假设的 AuthResult 和 User 类定义(实际使用时请参考插件文档)
class AuthResult {
  final bool isSuccessful;
  final User? user;

  AuthResult({required this.isSuccessful, this.user});
}

class User {
  final String displayName;

  User({required this.displayName});
}

注意:上述代码中的ArcanaAuth类、AuthResult类和User类是基于假设的,因为实际的arcana_auth插件可能会有不同的API。你应该参考该插件的官方文档来了解如何正确使用它。如果arcana_auth插件存在并且文档可用,你应该按照文档中的指导来修改上述示例代码。

另外,如果arcana_auth插件不支持直接启动第三方身份验证流程,你可能需要使用如url_launcherwebview_flutter等插件来打开第三方登录页面,并处理回调。

回到顶部