前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一键登录只需1秒,赶紧了解一下

一键登录只需1秒,赶紧了解一下

作者头像
AWeiLoveAndroid
发布2019-07-03 11:32:33
2.9K0
发布2019-07-03 11:32:33
举报
文章被收录于专栏:Flutter入门到实战

作为一个开发者,开发任何一个App都少不了登陆功能(个别特例除外),传统的一般只有3种:账号(邮箱)密码、短信验证、扫码登陆。但是这三种方式都太繁琐,如果忘记密码,就可能需要向你的密保邮箱或者手机发送验证码,重新填写密码,然后再去登陆,这个过程很麻烦。不光是一个开发者,作为一个用户来说,我也深受其害(当然也有一些app使用人脸解锁、指纹识别、手势解锁等功能,但是不太常见)。后来上网查阅资料,移动、电信、联通都有各自的一键登录SDK出台,同时市面上也有一些其它的一键登录的SDK出现。由于我是sharesdk的老用户,无意间发现它们官网有一个mob秒验,我就体验了一下,下面详细的讲解一下我的整个使用过程。

一、开发者账号和管理中心

(一)打开官网注册账号,然后登陆进去。点击右上角的产品中心

注:为了更好地使用产品,请填写实名认证信息。

(二)点击开发者平台,进入管理控制台
(三)创建应用,应用名称建议和你开发的应用名称保持一致。
(四)完善应用信息,便于审核通过。
(五)添加秒验功能模块

点击秒验右侧的+,然后在弹窗中选择确定添加

然后点击OK

(六)提交审核

点击秒验,点击立即审核

然后填写应用类型、所属行业、应用简介、平台、包名和签名。

这里着重强调一下,如果你不知道你的App的签名是什么,可以使用这个工具类。(项目创建签名之后,获取了签名,再来这个应用审核填写签名信息。)

代码语言:javascript
复制
/**
 * 描述:
 * 获取签名信息工具类
 */
public class PackageUtils {

    private static final char[] hexDigits = {48, 49, 50, 51, 52, 53, 54, 55,
            56, 57, 97, 98, 99, 100, 101, 102};
    private static final String TAG = "PackageUtils".getClass().getSimpleName();


    /**
     * 获取当前应用程序的包名
     *
     * @param context 上下文对象
     * @return 返回包名
     */
    public String getAppPackageName(Context context) {
        //当前应用pid
        int pid = android.os.Process.myPid();
        //任务管理类
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //遍历所有应用
        List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo info : infos) {
            if (info.pid == pid) {
                return info.processName;
            }
        }
        return "";
    }


    /**
     * 获取32位的包签名
     */
    public String getAppSignature(Activity activity) {
        PackageManager manager = activity.getPackageManager();
        /** 通过包管理器获得指定包名包含签名的包信息 **/
        PackageInfo packageInfo = null;
        try {
            // 传入包名
            packageInfo = manager.getPackageInfo(getAppPackageName(activity), PackageManager.GET_SIGNATURES);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        /******* 通过返回的包信息获得签名数组 *******/
        Signature[] signatures = packageInfo.signatures;
        String  result = hexdigest(signatures[0].toByteArray());
        if (result != null) {
            Log.d(TAG, "签名: " + result);
            return result;
        } else {
            Log.d(TAG, "没获得签名,请重试");
        }
        return null;
    }

    public String hexdigest(byte[] paramArrayOfByte) {
        try {
            MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
            localMessageDigest.update(paramArrayOfByte);
            byte[] arrayOfByte = localMessageDigest.digest();
            char[] arrayOfChar = new char[32];
            int i = 0;
            int j = 0;
            while (true) {
                if (i >= 16) {
                    return new String(arrayOfChar);
                }
                int k = arrayOfByte[i];
                int m = j + 1;
                arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
                j = m + 1;
                arrayOfChar[m] = hexDigits[(k & 0xF)];
                i++;
            }
        } catch (Exception localException) {
        }
        return null;
    }

}

然后在你的首个 ActivityonCreate() 或者 ApplicationonCreate() 方法里面加入两行代码,通过日志就可以查看了。

代码语言:javascript
复制
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 加入两行代码
        String appSignature = new PackageUtils().getAppSignature(MainActivity.this);
        Log.d("MainActivity ", "32位的签名为: " + appSignature);
    }
}

如果嫌弃麻烦,可以直接用命令行获取。

  • 前提:1.把jdk里面的`keytool.exe所在路径加入环境变量。2.生成签名文件,这里的命令最后一个参数需要签名文件存放路径。
代码语言:javascript
复制
 keytool -list -v -keystore C:\Users\Administrator\Desktop\data.jks

经测试,这两者获取的签名信息是一致的。

(七)审核中

审核完成就可以愉快的开发了。


二、安装SDK包和使用

根目录的gradle文件:

module的gradle文件:

下载SDK包:

出现一个错误:

解决问题:

经过这几步我们已经配置好了,接下来就是编写代码了。


三、核心代码解析

初始化SDK

在我们的Application文件里面onCreate方法里声明初始化:

代码语言:javascript
复制
MobSDK.init(this);

或者直接在Manifest.xml里面appliaction节点添加属性android:name="com.mob.MobApplication"

预登陆:提前调用预登录接口,可以加快免密登录过程,提高用户体验

代码语言:javascript
复制
SecVerify.preVerify(new OperationCallback() {
            @Override
            public void onComplete(Object data) {
                // Nothing to do
            }

            @Override
            public void onFailure(VerifyException e) {
                // Nothing to do
            }
        });

免密登录:

代码语言:javascript
复制
 SecVerify.verify(new MyVerifyCallback());

// 核心类
 class MyVerifyCallback extends VerifyCallback{

        @Override
        public void onOtherLogin() {
            // 用户点击“其他登录方式”,处理自己的逻辑
            CommonProgressDialog.dismissProgressDialog();
            Toast.makeText(MainActivity.this, "其他账号登录", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onComplete(VerifyResult data) {
            CommonProgressDialog.dismissProgressDialog();
            if (data != null) {
                Log.d(TAG, data.toJSONString());
                // 获取授权码成功,将token信息传给应用服务端,再由应用服务端进行登录验证,此功能需由开发者自行实现
                CommonProgressDialog.showProgressDialog(MainActivity.this);
                // 自己的登陆逻辑
                LoginTask.getInstance().login(data, new ResultListener<LoginResult>() {
                    @Override
                    public void onComplete(LoginResult data) {
                        CommonProgressDialog.dismissProgressDialog();
                        Log.d(TAG, "Login success. data: " + data.toJSONString());
                        vibrate();
                        // 服务端登录成功,跳转成功页
                        gotoSuccessActivity(data);
                    }

                    @Override
                    public void onFailure(DemoException e) {
                        // 登录失败
                        Log.e(TAG, "login failed", e);
                        CommonProgressDialog.dismissProgressDialog();
                        // 错误码
                        int errCode = e.getCode();
                        // 错误信息
                        String errMsg = e.getMessage();
                        // 更详细的网络错误信息可以通过t查看,请注意:t有可能为null
                        Throwable t = e.getCause();
                        String errDetail = null;
                        if (t != null) {
                            errDetail = t.getMessage();
                        }

                        String msg = "获取授权码成功,应用服务器登录失败" + "\n错误码: " + errCode + "\n错误信息: " + errMsg;
                        if (!TextUtils.isEmpty(errDetail)) {
                            msg += "\n详细信息: " + errDetail;
                        }
                        if (!devMode) {
                            msg = "当前网络异常";
                        }
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }

        @Override
        public void onFailure(VerifyException e) {
            // 登录失败
            CommonProgressDialog.dismissProgressDialog();
            Log.e(TAG, "verify failed", e);
            // 错误码
            int errCode = e.getCode();
            // 错误信息
            String errMsg = e.getMessage();
            // 更详细的网络错误信息可以通过t查看,请注意:t有可能为null
            Throwable t = e.getCause();
            String errDetail = null;
            if (t != null) {
                errDetail = t.getMessage();
            }

            String msg = "错误码: " + errCode + "\n错误信息: " + errMsg;
            if (!TextUtils.isEmpty(errDetail)) {
                msg += "\n详细信息: " + errDetail;
            }
            if (!devMode) {
                msg = "当前网络异常";
                if (errCode == VerifyErr.C_ONE_KEY_USER_CANCEL_GRANT.getCode()
                        || errCode == VerifyErr.C_LACK_OF_PERMISSIONS.getCode()
                        || errCode == VerifyErr.C_NO_SIM.getCode()
                        || errCode == VerifyErr.C_UNSUPPORTED_OPERATOR.getCode()) {
                    msg = errMsg;
                }
            }
            Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    }



  private void gotoSuccessActivity(LoginResult data) {
        Intent i = new Intent(this, SuccessActivity.class);
        i.putExtra(Const.EXTRAS_DEMO_LOGIN_RESULT, data);
        startActivityForResult(i, REQUEST_CODE);
    }

    private void vibrate() {
        Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
        if (vibrator != null) {
            if (Build.VERSION.SDK_INT >= 26) {
                VibrationEffect vibrationEffect = VibrationEffect.createOneShot(500, 20);
                vibrator.vibrate(vibrationEffect);
            } else {
                vibrator.vibrate(500);
            }
        }
    }

自定义授权页(这个不是重点就不做过多展开了)

更多详情,请查看官方文档:http://wiki.mob.com/secverify集成文档


四、Demo示例图解

点击 一键认证

加载进度提示:

点击登陆(默认是同意协议的)

验证成功

提示:第一次验证验证比较慢,大概5秒左右。当第一次验证成功之后,再次进入App,不到1秒就可以验证登陆。


五、注意事项:

(一)必须打开流量,秒验是通过4G网络来确定手机号的。我刚开始不知道,打开的wifi,未开启流量导致识别失败,后来开启了流量之后,OK了。
(二)别忘了加权限。
代码语言:javascript
复制
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_SETTINGS" /> 
<uses-permission android:name="android.permission.GET_TASKS" />
(三)如果是双卡手机,请确保拨号和上网都使用同一张SIM卡,否则会出错误。(我手机的两张卡分别:一张移动,一张联通的SIM卡)

请看以下截图:

1.拨号移动,上网联通。

  • 设置拨号移动,上网联通:
  • 运行出错示例图:

2.拨号联通,上网移动。

  • 设置拨号联通,上网移动:
  • 运行出错示例图:

六、免密登陆大致流程

我国三大运营商都有对应的免密登录的SDK出台,我搜索了移动、电信、联通的关于一键登录的SDK文档,发现移动的文档写的最完整,电信的一般,联通的官网打不开了。

具体文档链接如下:

一键登录的系统交互流程都是差不多的,主要分为四个步骤:

  • 第一步,号码认证SDK初始化。
  • 第二步,唤起授权页。
  • 第三步,同意授权并登录。
  • 第四步,发起取号。

具体如下图所示:


七、优缺点:

优点:

  • 1.用户输入手机号码或获得用户授权后,一键即可完成认证,方便快捷,省时省力,减少登陆时的耗时。大概1秒即可登陆,太方便了。
  • 2.减少忘记账号密码时的短信和邮箱麻烦,你只要有手机号就可以登陆了。比普通的手机短信验证方便多了。
  • 3.支持中国三大运营商全网手机号码认证,一点接入,全国全网覆盖。
  • 4.适用于以手机号进行注册、登陆、安全风控的场景,可实现用户无感知校验,拓宽校验场景。
  • 5.针对双卡手机,可以一键切换手机号码验证,也挺方便的。

缺点:

  • 1.通话和网络的SIM卡必须为同一张卡。否则会导致验证失败。
  • 2.请确保打开流量,否者会导致验证失败。
  • 3.请确保手机卡正常使用,停机欠费可能导致验证失败。
  • 4.官方文档建议完善一下,入口有点不好找,建议完善一下。另外建议把常见问题和开发者最关心的问题都加上去。

至于是否收费,以及收费标准如何,这就不是我能够操心的事了,请看官方文档或者咨询相关客服。我只是个开发人员,既然mob秒验这么好用的话,我当然会支持的。


八、相关资料下载:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.07.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、开发者账号和管理中心
    • (一)打开官网注册账号,然后登陆进去。点击右上角的产品中心。
      • (二)点击开发者平台,进入管理控制台。
        • (三)创建应用,应用名称建议和你开发的应用名称保持一致。
          • (四)完善应用信息,便于审核通过。
            • (五)添加秒验功能模块
              • (六)提交审核
                • (七)审核中
                • 二、安装SDK包和使用
                • 三、核心代码解析
                • 四、Demo示例图解
                • 五、注意事项:
                  • (一)必须打开流量,秒验是通过4G网络来确定手机号的。我刚开始不知道,打开的wifi,未开启流量导致识别失败,后来开启了流量之后,OK了。
                    • (二)别忘了加权限。
                      • (三)如果是双卡手机,请确保拨号和上网都使用同一张SIM卡,否则会出错误。(我手机的两张卡分别:一张移动,一张联通的SIM卡)
                      • 六、免密登陆大致流程
                      • 七、优缺点:
                      • 八、相关资料下载:
                      相关产品与服务
                      短信
                      腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档