天天看點

多賬号統一登陸,怎麼實作?

現在幾乎大部分的 App 都支援使用多個第三方賬号進行登入,如:微信、QQ、微網誌等,我們把此稱為多賬号統一登陸。而這些賬号的表設計,流程設計至關重要,不然後續擴充性賊差。

本文不提供任何代碼實操,但是梳理一下部落客根據我司賬号子產品的設計,提供思路,僅供參考。

一、 自建的登陸體系

1.1.1 手機号登陸注冊

該設計的思路是每個手機号對應一個使用者,手機号為必填項。

流程:

首先輸入手機号,然後發送到服務端。先判斷該手機号是否存在賬号,如果沒有,就會生成随機驗證碼,将手機号和驗證碼綁定到 Redis中,并設定一定的過期時間(過期時間一般是5分鐘,這就是我們一般手機驗證碼的有效期),最後将驗證碼通過短信發送給使用者。

使用者接收到驗證碼後,在界面填寫驗證碼以及密碼等基礎資訊,然後将這些資料發送服務端。服務端收到後,先判斷在 Redis裡面這個手機号對應的驗證碼是否一緻,,失敗就傳回錯誤碼,成功就給使用者建立一個賬号和儲存密碼。

注冊成功後,使用者即可通過自己的 手機号+密碼進行登陸。

問題:

使用者體驗差,需要完成擷取驗證碼,填寫驗證碼/密碼/使用者名等諸多的資訊完成注冊,然後才能使用;

容易遺忘密碼,遺忘後,隻能通過忘記密碼來重新設定密碼。

1.1.2 優化注冊登陸

該方案的思路是弱化密碼的必填性,即無論使用者是否注冊過,可通過 手機号+驗證碼 直接進行登陸(保留 手機号+密碼登入的方式)。

輸入手機号,然後發送到服務端。服務端生成随機驗證碼,将手機号和驗證碼綁定到 Redis中,并設定一定的過期時間(過期時間一般是5分鐘,這就是我們一般手機驗證碼的有效期),最後将驗證碼通過短信發送給使用者。

使用者接收到驗證碼後,在界面隻需填寫收到的驗證碼,送出到服務端。服務端收到後,先判斷在 Redis裡面這個手機号對應的驗證碼是否一緻,失敗就傳回錯誤碼,成功就直接登入。如果是老使用者,直接拉取使用者資訊;如果是新使用者,則提示他可以完善使用者資訊(不強制)。

使用者通過 手機号+驗證碼登入後,也可選擇設定密碼,然後就可以通過 手機号+密碼的方式登入,即:密碼是非必填項。

使用者表設計:

多賬号統一登陸,怎麼實作?

1.2 引入第三方賬戶方案

1.2.1 微網誌登入

進入 Web2.0 時代 ,微網誌開放了第三方網站登入, 産品說, 這個我們得要, 加個用微網誌帳号就能登入我們的 App吧,而且得和我們自己的使用者表關聯。

用戶端調用微網誌登入的界面,進行輸入使用者名、密碼,登入成功後,會傳回 access_token,通過 access_token調取 API接口擷取使用者資訊。

服務端通過使用者資訊在我們使用者表建立一個賬号,以後,該第三方賬号即可通過該微網誌賬号直接進行登陸。

微網誌使用者資訊表設計:

多賬号統一登陸,怎麼實作?

1.2.2 噩夢來臨

緊接着, QQ又開放使用者登入了, 微信開放使用者登入了,網易開發使用者登入了。。。。。。一下子要接入好多家第三方登入了, 隻能按照 “微網誌使用者資訊表” 建立一個表,重寫一套各個第三方登入。

二、 優化賬号體系

2.1 原賬号體系分析

自建登陸體系:無論 手機号+密碼 , 還是 手機号+驗證碼 , 都是一種 使用者資訊+密碼 的驗證形式;

第三方登入:也是 使用者資訊+密碼 的形式, 使用者資訊即第三方系統中的 ID(第三方系統中的唯一辨別), 密碼即 access_token, 隻不過是一種有使用時效定期修改的密碼。

2.2 新的賬号體系

2.2.1 資料表設計

使用者基礎資訊表:

多賬号統一登陸,怎麼實作?

使用者授權資訊表:

多賬号統一登陸,怎麼實作?

說明:

使用者表分為 使用者基礎資訊表 + 使用者授權資訊表;

使用者資訊表不儲存任何密碼, 不儲存任何登入資訊(如使用者名, 手機号, 郵箱), 隻留有昵稱、頭像等基礎資訊; 所有和授權相關,都放在使用者資訊授權表, 使用者資訊表和使用者授權表是一對多的關系 。

2.2.2 登入流程

手機号+驗證碼

沿用之前的方案。

郵箱/手機号+密碼:

使用者填寫 郵箱/手機号+密碼; 請求登入的時候, 先判斷類型, 如手機号登入為例:

使用 type='phone' 結合 identifier='手機号' 查找, 如有, 取出并判斷 password_hash(密碼)是否和該條目的 credential 相符, 相符則通過驗證, 随後通過 user_id 擷取使用者資訊;

第三方登入, 如微信登入:

查詢 type='weixin' 結合 identifier='微信 openId', 如果有記錄, 則直接登入成功, 并更新 token; 假設與微信伺服器通信不被劫持的情況下無需判斷憑證問題。

2.2.3 優缺點

優點:

登入類型無限擴充, 新增登入類型的開發成本顯著降低;

原來條件下, 應用需要驗證手機号是否已驗證和郵箱是否已驗證, 需要相對應多一個字段如 phone_verified 和 email_verified, 如今隻要在 使用者授權資訊表 表中增加一個統一的 verified字段, 每種登入方式都可以直覺看到是否已驗證情況;

在 使用者授權資訊表 添加相應的時間和 IP 位址, 就可以更加完整地跟蹤使用者的使用習慣, 比如:已經不使用微網誌登入兩年多, 已經綁定微信 300天;

如果你說郵箱和手機号就是使用者資訊的組成部分, users 表盡管拓展, users 表裡依然有email , phone , 但他們僅僅作為“展示用途”,和昵稱,頭像或者性别這些屬性沒有本質差別;

可按需綁定任意數量的同類型登入方式, 即一個使用者可以綁定多個微信, 可以有多個郵箱, 可以有多個手機号。當然你也可以限制一種登入方式隻有一條記錄;

缺點 :

使用者同時存在郵箱、使用者名、手機号等多種站内登入方式時, 改密碼時必須一起改, 否則就變成了 郵箱+新密碼, 手機号+舊密碼都可以登入, 肯定是很詭異的情況;

代碼量增加了, 有些情況下邏輯判斷增加了, 難度增大了; 舉個例子, 無論使用者是否已登入, 無論使用者是否已注冊過, 都是點選同一連結前往微網誌第三方授權後傳回, 可能出現幾種情況:

該微網誌在本站未注冊過, 很好, 直接給他注冊關聯并登入;

該微網誌已經在本站存在, 目前使用者未登入, 直接登入成功;

該微網誌未在本站注冊, 但目前使用者已經登入并關聯的是另一個微網誌帳号, 作何處理取決于是否允許綁定多個微網誌帳号;

該微網誌未在本站注冊過, 目前使用者已登入, 嘗試進行綁定操作;

該微網誌已經注冊, 使用者又已使用該帳号登入, 為何他重複綁定自己;

該微網誌已經在本站存在, 但目前使用者已經登入并關聯的是另一個微網誌帳号, 作何處理?

三、 一鍵登陸

3.1 背景

回顧一下 手機号+驗證碼 的登入方式:

輸入手機号、等待驗證碼短信、輸入驗證碼、點選登入。整個流程走完可能需要 20 秒以上,操作也比較繁瑣;

它是依賴短信網絡的,因為如果收不到短信,也就登入不了了。

從安全角度考慮,還存在驗證碼洩漏的風險。如果有人知道了你的手機号,并且竊取到了驗證碼,那他也能登入你的賬号了。

但回過頭來想一下,為什麼我們需要驗證碼?驗證碼的作用就是确定這個手機号是你的,那除了使用短信,是否還有别的方式對手機号進行認證?

如果能擷取到目前使用的手機号,就能對使用者輸入的号碼進行驗證了。但出于安全考慮,用戶端是無法直接擷取到手機号的,營運商則可以通過 SIM 卡資料查詢到。

現在營運商已經開放了相關的能力,現在我們可以在使用者輸入手機号後,通過調用營運商的接口,判斷使用者輸入的手機号是否和本地号碼一緻。這樣一來,使用者就省去了等待驗證碼短信、輸入驗證碼的過程,也不受短信網絡的限制,簡化了登入流程。

但再進一步想,如果營運商可以把目前的号碼直接傳回給我們,而不隻是用于驗證,那使用者連手機号都不需要填了。

這就是該部分的主角:一鍵登入 。

3.2 本機号碼認證

擷取到目前手機使用的手機卡号,直接使用這個号碼進行登入,這就是一鍵登入。

這種登入方式的好處是顯而易見的。它可以更友善、快捷地完成注冊、登入流程,将原本可能需要 20 秒的流程,縮短到了 2 秒左右,很大程度上提升了登入的使用者體驗。

主要步驟如下:

SDK 初始化:調用 SDK 的初始化方法,傳入項目在平台上的 AppKey 和 AppSecret。

喚起授權頁:調用 SDK 喚起授權接口。SDK 會先向營運商發起擷取手機号驗碼的請求,請求成功後跳轉到授權頁。授權頁會顯示手機号掩碼以及營運商協定給使用者确認。

同意授權并登入:使用者同意相關協定,點選授權頁面的登入按鈕,SDK 會請求本次取号的 token,請求成功後将 token 傳回給用戶端。

取号:将擷取到的 token 發送到我們自己的伺服器,由伺服器攜帶 token 調用營運商一鍵登入的接口,調用成功就傳回手機号碼了。伺服器用手機号進行登入或注冊操作,傳回操作結果給用戶端,完成一鍵登入。

四、小結

部落客看來,沒有最好的方案,選擇适用目前系統的設計即可。不要深究孰優孰劣,鞋合不合腳,隻有腳知道。