最近公司要求调研一键登陆业务,以下图所示 。php
本文将对比传统登陆方式和一键登陆,并简单介绍极光认证服务的集成。html
移动互联网发展到如今,帐号登陆 几乎成为了全部应用的标配功能。说到登陆方式,无外乎帐号密码登陆和验证码登陆。但是这两种方式,真的便捷安全吗?java
帐号密码登陆做为最原始的一种登陆方式,也是我最讨厌的一种登陆方式。android
从便捷性上来讲,用户得输入一个知足平台规则的用户名和密码,对于不一样的平台,都制定了本身的规则。虽然一般都没什么问题,可老是有一些有损用户体验的地方。git
有的时候想个密码和闯关同样,特别要求包含大小写字母的,用户容易遗忘。早期的 iCloud 就这么设定的,我还真忘记过,无奈之下,只能去找回密码。github
从安全性上来讲,也是有弊端的。我想不少人都喜欢 Write Once, Run Everywhere ,一个密码通吃全部场景。这自己就是一件极不安全的事情,常常有坊间流传的某某数据库泄露可能就把你的密码给暴露了,一堆黑产在后面每天撞库。另外一个方面,对于须要实名认证,或者限定用户认证信息的状况下,同一个用户能够无限制的注册帐号。虽然能够经过技术手段来限制,但总归带来必定的不便利。数据库
验证码登陆必定程度上解决了上面的问题。用户不须要想一个独特的密码,直接输入手机验证码便可。同时,手机号码的实名信息也在必定程度上防止了用户无限制的注册。即便如今大部分应用仍然会保留帐号密码登陆接口,但毋庸置疑,验证码登陆已经成为主流。安全
要说验证码登陆还有什么缺点?惟一一点就是还不够便利。用户正确输入手机号码,接收验证码,用户体验很差的 ROM 还得本身去填验证码,再碰到网络抽疯,只能倒回去选择帐号密码登陆。网络
秉着用户至上的原则,可让用户什么都不输入,就自动完成登陆过程,那就再好不过了。这就是今天要说的一键登陆。app
再回忆一下文章开头的 Gif,用户跳转到登陆页面以后,无需输入任何内容,页面自动展现用户的手机号码,只需点击一键登陆按钮便可,大大优化了用户体验,避免明文验证码的安全隐患,也没有密码方面的后顾之忧。
上面的登陆流程图来自中国移动免密登陆服务文档。依托运营商独有网关认证能力,用户一键受权便可获取本机号码完成登陆/注册。一样对于中国联通,中国电信,都提供了相似服务。
看到这,是否是有点崩溃。为了一个免密登陆,开发者居然要去对接三家 SDK 。一样做为开发者的我,平生最讨厌的就是集成 SDK ,且不说文档质量,同一个业务,三个 SDK 给应用体积带来的增加也不能接受。
那么有没有一个现成的 SDK ,整合三家运营商的服务呢?
我在几年前使用过极光社区的开源 IM 聊天 UI 组件 aurora-imui 。
Aurora IMUI 是个通用的即时通信(IM)UI 库,不特定于任何 IM SDK。完整的聊天列表和消息输入组件,同时支持 ANDROID/IOS/RN 。我调研过不少 IM 的 UI 组件库,不多有像 IMUI 这么功能完整的,所以对极光社区留下了很好的印象。本次我也调研了极光社区的免密一键登陆服务 —— 极光认证 。
简单说一下开通流程。
应用签名直接经过命令行获取。
keytool -list -v -keystore debug.keystore
复制代码
其中 debug.keystore
替换为你本身的签名文件。
RSA 公私钥能够经过 openssl
生成 。
openssl genrsa -out rsa_private.pem 1024
```ssh
执行后会在当前目录生成名为 **ras_private.pem** 的私钥文件,而后根据私钥文件生成公钥文件。
```java
openssl rsa -in rsa_private.pem -pubout -out rsa_public_key.pem
复制代码
执行后会在当前目录生成名为 ras_public_key.pem 的公钥文件。
推荐直接使用 jcenter 自动依赖。在 module 的 gradle 文件中添加以下依赖:
android {
......
defaultConfig {
applicationId "com.xxx.xxx" // 您应用的包名.
......
ndk {
//选择要添加的对应 cpu 类型的 .so 库。
abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
// 还能够添加 'x86', 'x86_64'
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "你的 Appkey ", //Portal上注册的包名对应的 appKey.
JPUSH_CHANNEL : "developer-default", //暂时填写默认值便可.
]
......
}
......
}
dependencies {
......
compile 'cn.jiguang.sdk:jverification:2.3.4' // 此处以2.3.4 版本为例。
compile 'cn.jiguang.sdk:jcore:2.1.2' // 此处以JCore 2.1.2 版本为例。
......
}
复制代码
在清单文件作以下配置。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="您应用的包名" android:versionCode="100" android:versionName="1.0.0" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
<!-- Required -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!-- Optional -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name="Your Application Name">
<!-- since 2.0.0 optional 可选项,使用一键登陆功能必须添加 -->
<!-- since 2.1.1 optional 可选项,经过screenOrientation设置受权页面横竖屏展现 -->
<activity android:name="com.cmic.sso.sdk.activity.OAuthActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait" android:launchMode="singleTop">
</activity>
<!-- since 2.0.0 optional 可选项,使用一键登陆功能必须添加 -->
<!-- since 2.1.1 optional 可选项,经过screenOrientation设置受权页面横竖屏展现 -->
<activity android:name="com.cmic.sso.sdk.activity.LoginAuthActivity" android:theme="@android:style/Theme.Holo.NoActionBar" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait" android:launchMode="singleTop">
</activity>
<!-- since 2.0.0 optional 可选项,使用一键登陆功能必须添加 -->
<!-- since 2.1.1 optional 可选项,经过screenOrientation设置受权页面横竖屏展现 -->
<activity android:name="cn.jiguang.verifysdk.CtLoginActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:theme="@android:style/Theme.Holo.NoActionBar" android:screenOrientation="portrait" android:launchMode="singleTop">
</activity>
<!-- Required -->
<meta-data android:name="JPUSH_APPKEY" android:value="您应用的Appkey"/>
<meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
</application>
</manifest>
复制代码
在 Application 中进行初始化。
JVerificationInterface.init(this, new RequestCallback<String>() {
@Override
public void onResult(int code, String result) {
......
}
})
复制代码
直接来看一键登陆接口。
JVerificationInterface.loginAuth(final Context context, LoginSettings settings, final VerifyListener listener)
使用以下:
LoginSettings settings = new LoginSettings();
settings.setAutoFinish(true);//设置登陆完成后是否自动关闭受权页
settings.setTimeout(15 * 1000);//设置超时时间,单位毫秒。 合法范围(0,30000],范围之外默认设置为10000
settings.setAuthPageEventListener(new AuthPageEventListener() {
@Override
public void onEvent(int cmd, String msg) {
//do something...
}
});//设置受权页事件监听
JVerificationInterface.loginAuth(this, settings, new VerifyListener() {
@Override
public void onResult(int code, String content, String operator) {
if (code == 6000){
Log.d(TAG, "code=" + code + ", token=" + content+" ,operator="+operator);
}else{
Log.d(TAG, "code=" + code + ", message=" + content);
}
}
});
复制代码
6000
表明成功。
可是在实际开发中并不建议直接这样使用。一键登陆须要依赖预取号结果,若是没有预取号,一键登陆时会自动预取号。建议拉起受权页前,好比在开屏页或者业务入口页预先调用一键登陆预取号接口进行预取号,能够提高受权页拉起速度,优化体验。
一键登陆预取号接口以下所示。
JVerificationInterface.preLogin(Context context, int timeOut, PreLoginListener listener)
JVerificationInterface.preLogin(this, 5000,new PreLoginListener() {
@Override
public void onResult(final int code, final String content) {
Log.d(TAG,"[" + code + "]message=" + content );
}
});
复制代码
返回的 code 为 7000
表示获取成功。注意,不要在预取号回调中重复调用预取号或者拉起受权页接口。
另外,在使用前记得判断当前网络环境是否支持。
JVerificationInterface.checkVerifyEnable(Context context)
boolean verifyEnable = JVerificationInterface.checkVerifyEnable(this);
if(!verifyEnable){
Log.d(TAG,"当前网络环境不支持认证");
return;
}
复制代码
通过个人实测,在仅开启 Wifi ,关闭数据流量的状况下,是没法进行一键登陆的。此时应提示用户使用帐号密码或者验证码登陆。
-dontoptimizefankan
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
-dontwarn com.cmic.**
-keep class com.cmic.** { *; }
-dontwarn com.unicom.**
-keep class com.unicom.** { *; }
-dontwarn cn.com.chinatelecom.**
-keep class cn.com.chinatelecom.** { *; }
复制代码
以上只是简单介绍了极光认证的使用,新开通用户都会赠送 1000 次体验。更多详细内容能够参见 官方文档 ,也能够直接下载 官方 Demo 。相信对于开发者来讲,什么都不如一个 demo 来的实在。
翻看 aurora-imui 时,发现极光还提供了各类服务的插件。
极光认证也提供了 Android,IOS,Web,React Native,Flutter,Cordova 等各类版本,知足开发者的各类需求。掘金上也看到了 Flutter 开发者的推荐, 本机号码一键登陆!推荐 Flutter 极光认证插件 。
一键登陆必定会是将来的趋势,若是你尚未了解过,那就快来体验吧 !