• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

flutter 集成极光一键登录

武飞扬头像
YML_426
帮助1

1.开通极光认证

极光官网创建应用后,在【认证设置】的【集成设置】中填写信息,Android的应用签名需要下载签名工具获取,ios填写Bundle ID,填写完毕后提交审核

学新通

在【认证设置】的【一键登录】中填写RSA 加密公钥

学新通

 加密公钥在在线生成公钥私钥对,RSA公私钥生成-ME2在线工具中获取,开通需要集成的平台

注意:RSA加密公钥位数1024位,密钥格式PKCS#8

2.引入插件及相关配置

  1.  
    dependencies:
  2.  
    jverify: 2.2.8

在android/app/build.gradle文件中进行以下配置:

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

3. 极光认证初始化

在登录界面initState进行初始化:

  1.  
    import 'package:jverify/jverify.dart';
  2.  
     
  3.  
    final Jverify jverify = new Jverify();
  4.  
     
  5.  
    /// 统一 key
  6.  
    final String f_result_key = "result";
  7.  
     
  8.  
    /// 错误码
  9.  
    final String f_code_key = "code";
  10.  
     
  11.  
    /// 回调的提示信息,统一返回 flutter 为 message
  12.  
    final String f_msg_key = "message";
  13.  
     
  14.  
    /// 运营商信息
  15.  
    final String f_opr_key = "operator";
  16.  
     
  17.  
    @override
  18.  
    void initState() {
  19.  
    await initPlatformState();
  20.  
    await isInitSuccess();
  21.  
    await preLogin();
  22.  
    }
  23.  
     
  24.  
     
  25.  
    void initPlatformState() {
  26.  
    // 初始化 SDK 之前添加监听
  27.  
    jverify.addSDKSetupCallBackListener((JVSDKSetupEvent event) {
  28.  
    print("receive sdk setup call back event :${event.toMap()}");
  29.  
    });
  30.  
     
  31.  
    // 是否打开调试模式
  32.  
    jverify.setDebugMode(true);
  33.  
     
  34.  
    // 初始化sdk
  35.  
    jverify.setup(
  36.  
    appKey: "填写应用的AppKey",
  37.  
    channel: "devloper-default"
  38.  
    );
  39.  
     
  40.  
    // 授权页面点击事件监听
  41.  
    jverify.addAuthPageEventListener((JVAuthPageEvent event) {
  42.  
    print("receive auth page event :${event.toMap()}");
  43.  
    });
  44.  
    }
  45.  
     
  46.  
    /// sdk 初始化是否完成
  47.  
    void isInitSuccess() {
  48.  
    jverify.isInitSuccess().then((map) {
  49.  
    bool result = map[f_result_key];
  50.  
    if (result) {
  51.  
    print("极光一键登录sdk 初始化成功");
  52.  
    } else {
  53.  
    print("极光一键登录sdk 初始化失败");
  54.  
    }
  55.  
    });
  56.  
    }
  57.  
     
  58.  
    // 登录预取号
  59.  
    void preLogin() {
  60.  
    // 判断当前的手机网络环境是否可以使用认证。
  61.  
    jverify.checkVerifyEnable().then((map) {
  62.  
    bool result = map[f_result_key];
  63.  
    if (result) {
  64.  
    jverify.preLogin().then((map) {
  65.  
    print("预取号接口回调:${map.toString()}");
  66.  
    int code = map[f_code_key];
  67.  
    String message = map[f_msg_key];
  68.  
    print("[$code] message = $message");
  69.  
    });
  70.  
    } else {
  71.  
    print("[2016],msg = 当前网络环境不支持认证");
  72.  
    }
  73.  
    });
  74.  
    }
学新通

 4.点击一键登录按钮拉起授权页

在登录页我们需要一个一键登录的按钮,点击后拉起极光的授权页

  1.  
    GestureDetector(
  2.  
    onTap: (){
  3.  
    loginAuth();
  4.  
    },
  5.  
    child: Text(
  6.  
    '一键登录'
  7.  
    ),
  8.  
    ),
  1.  
    /// SDK 请求授权一键登录
  2.  
    void loginAuth() {
  3.  
    jverify.checkVerifyEnable().then((map) {
  4.  
    bool result = map[f_result_key];
  5.  
    if (result) {
  6.  
    final screenSize = MediaQuery.of(_context).size;
  7.  
    final screenWidth = screenSize.width;
  8.  
    final screenHeight = screenSize.height;
  9.  
    bool isiOS = Platform.isIOS;
  10.  
     
  11.  
    /// 自定义授权的 UI 界面,以下设置的图片必须添加到资源文件里,
  12.  
    /// android项目将图片存放至drawable文件夹下,可使用图片选择器的文件名,例如:btn_login.xml,入参为"btn_login"。
  13.  
    /// ios项目存放在 Assets.xcassets。
  14.  
     
  15.  
    JVUIConfig uiConfig = JVUIConfig();
  16.  
    uiConfig.authBackgroundImage = 'background_image';
  17.  
     
  18.  
    // 导航栏
  19.  
    uiConfig.navHidden = isiOS ? true : true;
  20.  
    uiConfig.navReturnBtnHidden = false;
  21.  
    uiConfig.navColor = isiOS ? Color(0xFF0C0D16).value : Colors.transparent.value;
  22.  
    uiConfig.navText = " ";
  23.  
    uiConfig.navTextColor = Colors.blue.value;
  24.  
    uiConfig.navReturnImgPath = "return_bg"; //图片必须存在
  25.  
     
  26.  
    // logo
  27.  
    uiConfig.logoWidth = 100;
  28.  
    uiConfig.logoHeight = 100;
  29.  
    uiConfig.logoOffsetY = 10;
  30.  
    uiConfig.logoVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
  31.  
    uiConfig.logoHidden = false;
  32.  
    uiConfig.logoImgPath = "logo";
  33.  
    uiConfig.logoHidden = true;
  34.  
     
  35.  
    // 号码
  36.  
    uiConfig.numberFieldWidth = 200;
  37.  
    uiConfig.numberFieldHeight = 40;
  38.  
    uiConfig.numFieldOffsetY = isiOS ? 144 : 144;
  39.  
    uiConfig.numberVerticalLayoutItem = isiOS ? JVIOSLayoutItem.ItemLogo : JVIOSLayoutItem.ItemNone;
  40.  
    uiConfig.numberColor = Colors.white.value;
  41.  
    uiConfig.numberSize = 26;
  42.  
     
  43.  
    // slogan
  44.  
    uiConfig.sloganOffsetY = isiOS ? 20 : 180;
  45.  
    uiConfig.sloganVerticalLayoutItem = JVIOSLayoutItem.ItemNumber;
  46.  
    uiConfig.sloganTextColor = Color(0xFF6E6E6E).value;
  47.  
    uiConfig.sloganTextSize = 14;
  48.  
    uiConfig.sloganHidden = true;
  49.  
     
  50.  
    // 登录按钮
  51.  
    uiConfig.logBtnWidth = MediaQuery.of(_context).size.width.toInt() - 100;
  52.  
    uiConfig.logBtnHeight = 50;
  53.  
    uiConfig.logBtnOffsetY = isiOS ? 350 : 500;
  54.  
    uiConfig.logBtnVerticalLayoutItem = isiOS ? JVIOSLayoutItem.ItemSlogan : JVIOSLayoutItem.ItemPrivacy;
  55.  
    uiConfig.logBtnText = "一键登录";
  56.  
    uiConfig.logBtnTextColor = Colors.white.value;
  57.  
    uiConfig.logBtnTextSize = 18;
  58.  
    uiConfig.logBtnTextBold = true;
  59.  
    uiConfig.logBtnBackgroundPath = "login_btn"; //图片必须存在
  60.  
    uiConfig.loginBtnNormalImage = "loginbtn"; //图片必须存在 only ios
  61.  
    uiConfig.loginBtnPressedImage = "loginbtn"; //图片必须存在 only ios
  62.  
    uiConfig.loginBtnUnableImage = "loginbtn"; //图片必须存在 only ios
  63.  
     
  64.  
    // 隐私协议栏
  65.  
    uiConfig.privacyHintToast = true; //设置隐私条款不选中时点击登录按钮默认显示toast。
  66.  
    uiConfig.privacyState = false; //设置隐私条款默认选中状态,默认不选中
  67.  
    uiConfig.privacyCheckboxSize = 20;
  68.  
    uiConfig.privacyCheckboxInCenter = true; //设置隐私条款checkbox是否相对协议文字纵向居中
  69.  
    uiConfig.privacyCheckboxHidden = false; //设置隐私条款checkbox是否隐藏
  70.  
     
  71.  
    uiConfig.privacyOffsetY = 15; // 隐私条款相对于授权页面底部下边缘 y 偏移
  72.  
    uiConfig.privacyVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
  73.  
    uiConfig.clauseColor = Color(0xFFFEFEFE).value;
  74.  
    uiConfig.privacyText = ["登录即代表同意"];
  75.  
    uiConfig.privacyTextSize = 13;
  76.  
    uiConfig.textVerAlignment = 1; //设置条款文字是否垂直居中对齐(默认居中对齐) 0是top 1是m 2是b
  77.  
    uiConfig.privacyWithBookTitleMark = true; //设置隐私条款运营商协议名是否加书名号
  78.  
    uiConfig.privacyTextCenterGravity = true; //隐私条款文字是否居中对齐(默认左对齐)
  79.  
     
  80.  
    // 授权页
  81.  
    uiConfig.statusBarColorWithNav = true; //授权页状态栏是否跟导航栏同色 only android
  82.  
    uiConfig.authStatusBarStyle = JVIOSBarStyle.StatusBarStyleDarkContent; //授权页状态栏样式设置 only iOS
  83.  
    uiConfig.virtualButtonTransparent = true; //授权页虚拟按键背景是否透明 only android
  84.  
     
  85.  
     
  86.  
    // 隐私协议 web 页 UI 配置
  87.  
    uiConfig.privacyStatusBarStyle = JVIOSBarStyle.StatusBarStyleDefault; //隐私协议web页 状态栏样式设置 only iOS
  88.  
    uiConfig.privacyNavColor = Color(0xFF0C0D16).value; // 导航栏颜色
  89.  
    uiConfig.privacyNavTitleTextColor = Colors.white.value; // 标题颜色
  90.  
    uiConfig.privacyNavTitleTextSize = 16; // 标题大小
  91.  
    uiConfig.privacyNavReturnBtnImage = "back"; //图片必须存在;
  92.  
     
  93.  
     
  94.  
    // 授权页弹窗模式 配置,选填
  95.  
    uiConfig.modelTransitionStyle = JVIOSUIModalTransitionStyle.CrossDissolve; //弹出方式 only ios
  96.  
     
  97.  
     
  98.  
    // 隐私页
  99.  
    uiConfig.privacyStatusBarColorWithNav = true; //隐私页web状态栏是否与导航栏同色 only android
  100.  
    uiConfig.privacyVirtualButtonTransparent = true; //隐私页web页虚拟按键背景是否透明 only android
  101.  
     
  102.  
     
  103.  
    //是否需要动画
  104.  
    uiConfig.needStartAnim = true; //设置拉起授权页时是否需要显示默认动画
  105.  
    uiConfig.needCloseAnim = true; //设置关闭授权页时是否需要显示默认动画
  106.  
    uiConfig.enterAnim = "activity_slide_enter_bottom"; // 拉起授权页时进入动画 only android
  107.  
    uiConfig.exitAnim = "activity_slide_exit_bottom"; // 退出授权页时动画 only android
  108.  
     
  109.  
    // 添加自定义的 控件 到授权界面
  110.  
    List<JVCustomWidget> widgetList = [];
  111.  
     
  112.  
     
  113.  
    /// 步骤 1:调用接口设置 UI
  114.  
    jverify.setCustomAuthorizationView(true, uiConfig,landscapeConfig: uiConfig, widgets: widgetList);
  115.  
     
  116.  
    /// 步骤 2:调用一键登录接口,极光提供了两种方式:同步(loginAuthSyncApi)和异步(loginAuth)
  117.  
     
  118.  
    /// 我使用的是同步,需要使用异步的在极光文档查看
  119.  
    /// 先,添加 loginAuthSyncApi 接口回调的监听
  120.  
    jverify.addLoginAuthCallBackListener((event) {
  121.  
    // 当code为6000时,message就是我们需要的token
  122.  
    print("监听获取返回数据:[${event.code}] message = ${event.message}");
  123.  
    print("通过添加监听,获取到 loginAuthSyncApi 接口返回数据,code=${event.code},message = ${event.message},operator = ${event.operator}");
  124.  
    String message = event.message;
  125.  
    getPhone(message);
  126.  
    });
  127.  
     
  128.  
    /// 再,执行同步的一键登录接口
  129.  
    jverify.loginAuthSyncApi(autoDismiss: true);
  130.  
     
  131.  
    } else {
  132.  
    print("[2016],msg = 当前网络环境不支持认证");
  133.  
    toast('当前网络环境不支持一键登录');
  134.  
    }
  135.  
    });
  136.  
    }
  137.  
     
  138.  
    // 将token传给后端,获取手机号
  139.  
    void getPhone(String token) async {
  140.  
    String url = "https://api.verification.jpush.cn/v1/web/loginTokenVerify";
  141.  
    Dio dio = new Dio();
  142.  
    dio.options.contentType = "application/json";
  143.  
    // 注意!!!将appKey和masterSecret以“appKey:masterSecret”的格式转为base64
  144.  
    dio.options.headers = {
  145.  
    "Authorization":"Basic 此处为转为base64的字符串",
  146.  
    };
  147.  
    Map<String, dynamic> params = {
  148.  
    "loginToken": token,
  149.  
    "exID": '',
  150.  
    };
  151.  
     
  152.  
    print("调用极光接口:$url 参数:$params");
  153.  
    Response response = await dio.post(url, data: params);
  154.  
     
  155.  
    var data = response.data;
  156.  
    String result = json.encode(data);
  157.  
    Map<String, dynamic> user = convert.jsonDecode(result);
  158.  
    print('极光返回值:$user');
  159.  
     
  160.  
    // 此处调后端一键登录接口,user['phone']是获取到的加密的手机号码,后端需要使用极光后台填写的公钥对应的私钥进行解密,方法内写登录逻辑即可
  161.  
    oneClickLogin(user['phone']);
  162.  
    }
学新通

 到此处极光一键登录的功能实现了

过程中还遇到了一些问题:

1.登录预取号jverify.preLogin()失败

可能是连接了WiFi网络的问题,关闭WiFi使用移动数据流量后成功

2.调用addLoginAuthCallBackListener时获取不到token,返回code:6001,message:fetch loginToken failed

这个问题把日志发给极光后反馈预取号过期,尝试运行了极光的demo后又运行了自己的项目又可以了......一行代码都没改。

后续又出现过这个问题,拉不起授权页,code有时返回6001有时返回2005,发日志给极光后反馈是运营商返回的报错,在网络双开或用户网络状况不好的情况下会发生。

总之感觉极光的一键登录不是很稳定,不是100%能使用。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkkifg
系列文章
更多 icon
同类精品
更多 icon
继续加载