Flutter は Jiguang のワンクリック ログインを統合します

1.オープンJiguang認定

Jiguang公式サイトでアプリを作成後、[認証設定]の[統合設定]に情報を入力します。Androidアプリの署名は署名ツールをダウンロードして取得する必要があり、iOSの場合はバンドルIDを入力します。完了後にレビューのために提出します

[認証設定]の[ワンクリックログイン]にRSA暗号化公開鍵を入力します。

 暗号化された公開鍵は、公開鍵と秘密鍵のペアのオンライン生成である RSA 公開鍵と秘密鍵の生成 - ME2 オンライン ツールから取得され、統合する必要があるプラットフォームが開かれます。

注: RSA 暗号化公開キーの数は 1024 ビット、キー形式は PKCS#8 です。

2. プラグインと関連構成の導入

dependencies:
  jverify: 2.2.8

android/app/build.gradle ファイルで次の構成を行います。

android: {
    ...
    manifestPlaceholders = [
        JPUSH_PKGNAME : applicationId, //填写信息时的应用包名
        JPUSH_APPKEY : "appkey", // 极光后台该应用对应的Appkey
		JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
    ]
    ...
}

3. Jiguang認証の初期化

ログイン インターフェイスの initState で初期化します。

import 'package:jverify/jverify.dart';

final Jverify jverify = new Jverify();

/// 统一 key
final String f_result_key = "result";

/// 错误码
final String f_code_key = "code";

/// 回调的提示信息,统一返回 flutter 为 message
final String f_msg_key = "message";

/// 运营商信息
final String f_opr_key = "operator";

@override
void initState() {
    await initPlatformState();
    await isInitSuccess();
    await preLogin();
}


void initPlatformState() {
    // 初始化 SDK 之前添加监听
    jverify.addSDKSetupCallBackListener((JVSDKSetupEvent event) {
        print("receive sdk setup call back event :${event.toMap()}");
    });

    // 是否打开调试模式
    jverify.setDebugMode(true);

    // 初始化sdk
    jverify.setup(
      appKey: "填写应用的AppKey",
      channel: "devloper-default"
    );

    // 授权页面点击事件监听
    jverify.addAuthPageEventListener((JVAuthPageEvent event) {
        print("receive auth page event :${event.toMap()}");
    });
}

/// sdk 初始化是否完成
void isInitSuccess() {
    jverify.isInitSuccess().then((map) {
        bool result = map[f_result_key];
        if (result) {
            print("极光一键登录sdk 初始化成功");
        } else {
            print("极光一键登录sdk 初始化失败");
        }
    });
}

// 登录预取号
void preLogin() {
    // 判断当前的手机网络环境是否可以使用认证。
    jverify.checkVerifyEnable().then((map) {
        bool result = map[f_result_key];
        if (result) {
            jverify.preLogin().then((map) {
                print("预取号接口回调:${map.toString()}");
                int code = map[f_code_key];
                String message = map[f_msg_key];
                print("[$code] message = $message");
            });
        } else {
            print("[2016],msg = 当前网络环境不支持认证");
        }
    });
}

 4. ワンクリックログインボタンをクリックして認証ページを表示します。

ログインページにはワンクリックでログインボタンが必要で、クリックするとJiguangの認証ページが表示されます。

GestureDetector(
    onTap: (){
        loginAuth();
    },
    child: Text(
        '一键登录'
    ),
),
/// SDK 请求授权一键登录
void loginAuth() {
    jverify.checkVerifyEnable().then((map) {
        bool result = map[f_result_key];
        if (result) {
            final screenSize = MediaQuery.of(_context).size;
            final screenWidth = screenSize.width;
            final screenHeight = screenSize.height;
            bool isiOS = Platform.isIOS;

            /// 自定义授权的 UI 界面,以下设置的图片必须添加到资源文件里,
            /// android项目将图片存放至drawable文件夹下,可使用图片选择器的文件名,例如:btn_login.xml,入参为"btn_login"。
            /// ios项目存放在 Assets.xcassets。

            JVUIConfig uiConfig = JVUIConfig();
            uiConfig.authBackgroundImage = 'background_image';

            // 导航栏
            uiConfig.navHidden = isiOS ? true : true;
            uiConfig.navReturnBtnHidden = false;
            uiConfig.navColor = isiOS ? Color(0xFF0C0D16).value : Colors.transparent.value;
            uiConfig.navText = " ";
            uiConfig.navTextColor = Colors.blue.value;
            uiConfig.navReturnImgPath = "return_bg"; //图片必须存在
            
            // logo
            uiConfig.logoWidth = 100;
            uiConfig.logoHeight = 100;
            uiConfig.logoOffsetY = 10;
            uiConfig.logoVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
            uiConfig.logoHidden = false;
            uiConfig.logoImgPath = "logo";
            uiConfig.logoHidden = true;

            // 号码
            uiConfig.numberFieldWidth = 200;
            uiConfig.numberFieldHeight = 40;
            uiConfig.numFieldOffsetY = isiOS ? 144 : 144;
            uiConfig.numberVerticalLayoutItem = isiOS ? JVIOSLayoutItem.ItemLogo : JVIOSLayoutItem.ItemNone;
            uiConfig.numberColor = Colors.white.value;
            uiConfig.numberSize = 26;

            // slogan
            uiConfig.sloganOffsetY = isiOS ? 20 : 180;
            uiConfig.sloganVerticalLayoutItem = JVIOSLayoutItem.ItemNumber;
            uiConfig.sloganTextColor = Color(0xFF6E6E6E).value;
            uiConfig.sloganTextSize = 14;
            uiConfig.sloganHidden = true;

            // 登录按钮
            uiConfig.logBtnWidth = MediaQuery.of(_context).size.width.toInt() - 100;
            uiConfig.logBtnHeight = 50;
            uiConfig.logBtnOffsetY = isiOS ? 350 : 500;
            uiConfig.logBtnVerticalLayoutItem = isiOS ? JVIOSLayoutItem.ItemSlogan : JVIOSLayoutItem.ItemPrivacy;
            uiConfig.logBtnText = "一键登录";
            uiConfig.logBtnTextColor = Colors.white.value;
            uiConfig.logBtnTextSize = 18;
            uiConfig.logBtnTextBold = true;
            uiConfig.logBtnBackgroundPath = "login_btn"; //图片必须存在
            uiConfig.loginBtnNormalImage = "loginbtn"; //图片必须存在 only ios
            uiConfig.loginBtnPressedImage = "loginbtn"; //图片必须存在 only ios
            uiConfig.loginBtnUnableImage = "loginbtn"; //图片必须存在 only ios

            // 隐私协议栏
            uiConfig.privacyHintToast = true; //设置隐私条款不选中时点击登录按钮默认显示toast。
            uiConfig.privacyState = false; //设置隐私条款默认选中状态,默认不选中
            uiConfig.privacyCheckboxSize = 20;
            uiConfig.privacyCheckboxInCenter = true; //设置隐私条款checkbox是否相对协议文字纵向居中
            uiConfig.privacyCheckboxHidden = false; //设置隐私条款checkbox是否隐藏

            uiConfig.privacyOffsetY = 15; // 隐私条款相对于授权页面底部下边缘 y 偏移
            uiConfig.privacyVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
            uiConfig.clauseColor = Color(0xFFFEFEFE).value;
            uiConfig.privacyText = ["登录即代表同意"];
            uiConfig.privacyTextSize = 13;
            uiConfig.textVerAlignment = 1; //设置条款文字是否垂直居中对齐(默认居中对齐) 0是top 1是m 2是b
            uiConfig.privacyWithBookTitleMark = true; //设置隐私条款运营商协议名是否加书名号
            uiConfig.privacyTextCenterGravity = true; //隐私条款文字是否居中对齐(默认左对齐)
          
            // 授权页  
            uiConfig.statusBarColorWithNav = true; //授权页状态栏是否跟导航栏同色 only android
            uiConfig.authStatusBarStyle = JVIOSBarStyle.StatusBarStyleDarkContent; //授权页状态栏样式设置 only iOS
            uiConfig.virtualButtonTransparent = true; //授权页虚拟按键背景是否透明 only android
            

            // 隐私协议 web 页 UI 配置
            uiConfig.privacyStatusBarStyle = JVIOSBarStyle.StatusBarStyleDefault; //隐私协议web页 状态栏样式设置 only iOS
            uiConfig.privacyNavColor = Color(0xFF0C0D16).value; // 导航栏颜色
            uiConfig.privacyNavTitleTextColor = Colors.white.value; // 标题颜色
            uiConfig.privacyNavTitleTextSize = 16; // 标题大小
            uiConfig.privacyNavReturnBtnImage = "back"; //图片必须存在;

            
            // 授权页弹窗模式 配置,选填
            uiConfig.modelTransitionStyle = JVIOSUIModalTransitionStyle.CrossDissolve; //弹出方式 only ios

      
            // 隐私页
            uiConfig.privacyStatusBarColorWithNav = true; //隐私页web状态栏是否与导航栏同色 only android
            uiConfig.privacyVirtualButtonTransparent = true; //隐私页web页虚拟按键背景是否透明 only android


            //是否需要动画
            uiConfig.needStartAnim = true; //设置拉起授权页时是否需要显示默认动画
            uiConfig.needCloseAnim = true; //设置关闭授权页时是否需要显示默认动画
            uiConfig.enterAnim = "activity_slide_enter_bottom"; // 拉起授权页时进入动画 only android
            uiConfig.exitAnim = "activity_slide_exit_bottom"; // 退出授权页时动画 only android

            // 添加自定义的 控件 到授权界面
            List<JVCustomWidget> widgetList = [];


            /// 步骤 1:调用接口设置 UI
            jverify.setCustomAuthorizationView(true, uiConfig,landscapeConfig: uiConfig, widgets: widgetList);

            /// 步骤 2:调用一键登录接口,极光提供了两种方式:同步(loginAuthSyncApi)和异步(loginAuth)

            /// 我使用的是同步,需要使用异步的在极光文档查看
            /// 先,添加 loginAuthSyncApi 接口回调的监听
            jverify.addLoginAuthCallBackListener((event) {
                // 当code为6000时,message就是我们需要的token
                print("监听获取返回数据:[${event.code}] message = ${event.message}");
                print("通过添加监听,获取到 loginAuthSyncApi 接口返回数据,code=${event.code},message = ${event.message},operator = ${event.operator}");
                String message = event.message;
                getPhone(message);
            });

            /// 再,执行同步的一键登录接口
            jverify.loginAuthSyncApi(autoDismiss: true);

        } else {
            print("[2016],msg = 当前网络环境不支持认证");
            toast('当前网络环境不支持一键登录');
        }
    });
}

// 将token传给后端,获取手机号
void getPhone(String token) async {
    String url = "https://api.verification.jpush.cn/v1/web/loginTokenVerify";
    Dio dio = new Dio();
    dio.options.contentType = "application/json";
    // 注意!!!将appKey和masterSecret以“appKey:masterSecret”的格式转为base64
    dio.options.headers = {
        "Authorization":"Basic 此处为转为base64的字符串",
    };
    Map<String, dynamic> params = {
        "loginToken": token,
        "exID": '',
    };

    print("调用极光接口:$url  参数:$params");
    Response response = await dio.post(url, data: params);

    var data = response.data;
    String result = json.encode(data);
    Map<String, dynamic> user = convert.jsonDecode(result);
    print('极光返回值:$user');

    // 此处调后端一键登录接口,user['phone']是获取到的加密的手机号码,后端需要使用极光后台填写的公钥对应的私钥进行解密,方法内写登录逻辑即可
    oneClickLogin(user['phone']);
}

 この時点で、Jiguang のワンクリック ログイン機能が実現されました。

この過程でいくつかの問題も発生します。

1. ログインプリフェッチ番号 jverify.preLogin() が失敗しました

WiFi ネットワークへの接続に問題がある可能性があります。WiFi をオフにしてモバイル データ トラフィックを使用すると、成功しました。

2. addLoginAuthCallBackListener を呼び出すときにトークンを取得できず、リターン コード: 6001、メッセージ: fetch loginToken failed が表示されます。

この問題については、Jiguang にログを送信した後、プリフェッチ番号の有効期限が切れたと報告されましたが、Jiguang のデモを実行してから独自のプロジェクトを実行してみると、再び正常になりました...コード行は変更されていません。

この問題は後になって再び発生し、認証ページを開くことができず、コードが 6001 を返すこともあれば、2005 を返すこともありました。ログを Jiguang に送信した後、オペレーターがエラー レポートを返したというフィードバックがありました。これはネットワークが切断されているときに発生するものです。二重に開かれているか、ユーザーのネットワーク状態が良好ではありません。

つまり、Jiguangのワンクリックログインはあまり安定しておらず、100%使いこなせるものではないように感じます。

おすすめ

転載: blog.csdn.net/YML_426/article/details/128915708