最近公司要求調研一鍵登錄業務,如下圖所示 。
本文將對比傳統登錄方式和一鍵登錄,並簡單介紹極光認證服務的集成。
傳統登錄方式
移動互聯網發展到現在,賬號登錄 幾乎成爲了所有應用的標配功能。說到登錄方式,無外乎賬號密碼登錄和驗證碼登錄。可是這兩種方式,真的便捷安全嗎?
賬號密碼登錄
賬號密碼登錄作爲最原始的一種登錄方式,也是我最討厭的一種登錄方式。
從便捷性上來說,用戶得輸入一個滿足平臺規則的用戶名和密碼,對於不同的平臺,都制定了自己的規則。雖然通常都沒什麼問題,可總是有一些有損用戶體驗的地方。
我想輸入中文,平臺只給輸入英文、字母、符號,或者反之
密碼長度限定,最少 6 位,8 位 ......
密碼輸入限定,最常見的,要求包含大小寫字母和數字
有的時候想個密碼和闖關一樣,特別要求包含大小寫字母的,用戶容易遺忘。早期的 iCloud 就這麼設定的,我還真忘記過,無奈之下,只能去找回密碼。
從安全性上來說,也是有弊端的。我想很多人都喜歡 Write Once, Run Everywhere ,一個密碼通吃所有場景。這本身就是一件極不安全的事情,經常有坊間流傳的某某數據庫泄露可能就把你的密碼給暴露了,一堆黑產在後面天天撞庫。另一個方面,對於需要實名認證,或者限定用戶認證信息的情況下,同一個用戶可以無限制的註冊賬號。雖然可以通過技術手段來限制,但總歸帶來一定的不便利。
驗證碼登錄
驗證碼登錄一定程度上解決了上面的問題。用戶不需要想一個獨特的密碼,直接輸入手機驗證碼即可。同時,手機號碼的實名信息也在一定程度上防止了用戶無限制的註冊。即使現在大部分應用仍然會保留賬號密碼登錄接口,但毋庸置疑,驗證碼登錄已經成爲主流。
要說驗證碼登錄還有什麼缺點?唯一一點就是還不夠便利。用戶正確輸入手機號碼,接收驗證碼,用戶體驗不好的 ROM 還得自己去填驗證碼,再碰到網絡抽瘋,只能倒回去選擇賬號密碼登錄。
秉着用戶至上的原則,可以讓用戶什麼都不輸入,就自動完成登錄過程,那就再好不過了。這就是今天要說的一鍵登錄。
一鍵登錄
再回憶一下文章開頭的 Gif,用戶跳轉到登錄頁面之後,無需輸入任何內容,頁面自動展示用戶的手機號碼,只需點擊一鍵登錄按鈕即可,大大優化了用戶體驗,避免明文驗證碼的安全隱患,也沒有密碼方面的後顧之憂。
上面的登錄流程圖來自中國移動免密登錄服務文檔。依託運營商獨有網關認證能力,用戶一鍵授權即可獲取本機號碼完成登錄/註冊。同樣對於中國聯通,中國電信,都提供了類似服務。
天翼開放平臺
中國移動互聯網能力開放平臺
小沃SAAS服務平臺
看到這,是不是有點崩潰。爲了一個免密登錄,開發者竟然要去對接三家 SDK 。同樣作爲開發者的我,生平最討厭的就是集成 SDK ,且不說文檔質量,同一個業務,三個 SDK 給應用體積帶來的增長也不能接受。
那麼有沒有一個現成的 SDK ,整合三家運營商的服務呢?
極光認證
我在幾年前使用過極光社區的開源 IM 聊天 UI 組件 aurora-imui 。
Aurora IMUI 是個通用的即時通訊(IM)UI 庫,不特定於任何 IM SDK。完整的聊天列表和消息輸入組件,同時支持 ANDROID/IOS/RN 。我調研過很多 IM 的 UI 組件庫,很少有像 IMUI 這麼功能完整的,因此對極光社區留下了很好的印象。本次我也調研了極光社區的免密一鍵登錄服務 —— 極光認證 。
準備工作
簡單說一下開通流程。
註冊 極光開發者賬號 ,然後完成 開發者認證 。
選擇要開通極光認證的應用程序,你也可以新建應用 。Android應用需要填寫 應用包名 和 應用簽名,並提供一個 RSA加密公鑰,一鍵登錄的手機號碼將用 RSA 公鑰加密後返回,開發者需使用對應私鑰解密。RSA加密公鑰位數是 1024位,密鑰格式是 PKCS#8 。公鑰對應的私鑰,我們要妥善保管,避免泄露。
應用簽名直接通過命令行獲取。
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 的公鑰文件。
集成 SDK
推薦直接使用 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 版本爲例。
......
}
Androidmanifest.xml 配置
在清單文件做如下配置。
<?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) {
......
}
})
API 介紹
直接來看一鍵登錄接口。
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.** { *; }
使用限制
支持國內三大運營商,中國移動、中國聯通、中國電信。由於運營商限制等原因,對於 Web SDK,目前不支持中國聯通
網絡支持中國移動 2G/3G/4G、中國聯通 3G/4G、中國電信 4G 。對於移動端用戶來說必須開啓數據流量
2G網絡下認證失敗率較高
支持雙卡手機,但只能以打開數據網絡的SIM卡進行認證
以上只是簡單介紹了極光認證的使用,新開通用戶都會贈送 1000 次體驗。更多詳細內容可以參見 官方文檔 ,也可以直接下載 官方 Demo 。相信對於開發者來說,什麼都不如一個 demo 來的實在。
總結
翻看 aurora-imui 時,發現極光還提供了各種服務的插件。
極光認證也提供了 Android,IOS,Web,React Native,Flutter,Cordova 等各種版本,滿足開發者的各種需求。掘金上也看到了 Flutter 開發者的推薦, 本機號碼一鍵登錄!推薦 Flutter 極光認證插件 。
一鍵登錄一定會是未來的趨勢,如果你還沒有了解過,那就快來體驗吧 !