app 登錄淺析

mr4831 7年前發布 | 12K 次閱讀 服務器 移動開發

1.登錄方式

(1)登錄方式

一般有以下幾種登錄方式

傳統的賬號密碼登錄,如下面的知乎賬號/密碼 登錄,賬號可以是郵箱,手機號或者賬戶名

手機驗證碼登錄,如下面的今日頭條手機驗證碼登錄

第三方登錄,如下面的額知乎日報,上面的今日頭條也一樣

還有一些新型的登錄方式,比如圖案鎖,指紋,語音驗證,虹膜掃描等等,這些都是在client進行驗證,或者是一種變種的賬號密碼形式,在這里不作討論。`為表述方便,分別使用 賬密驗證碼第三方 來表述上面三種登錄方式。

(2)登錄方式的大概流程

賬密:用戶在client輸入賬號密碼,發送到server端,server端進行database驗證,如果驗證通過則該用戶認證成功,否則認證失敗

驗證碼:用戶輸入手機號,并且點擊獲取驗證碼,server產生隨機驗證碼并打上過期時間,通過SMS傳輸給用戶,client輸入該驗證碼,傳到server進行判斷

第三方:第三方相對復雜一點,client需要先到第三方網站或者APP進行授權,授權后跳轉到server,server通過code碼獲取到相應的access_token,然后通過access_token獲得這個用戶在這個第三方的基本信息。

(3)登錄方式的優缺點以及適用場景

賬密:安全性相對較高,需要用戶輸入保護信息。使用場景較廣,一般的應用都能夠適用。

驗證碼:優點是便捷,缺點是安全系數相對較低,手機丟失即賬號丟失,一般用在驗證不是非常嚴密的應用,比如新聞資訊,地圖這種獲取咨詢的app或者一些即用即關的一些應用,比如滴滴,貨拉拉這種app,(注:內部支付有另外的驗證)。

第三方:優點同樣是便捷,比手機號還要編輯,都不需要輸入驗證碼。安全性需要依托第三方的可信度。不過現在微信,微博等第三方的登錄還是相對比較安全的。使用范圍相對較廣。便捷性方面不定,需要依托第三方的便捷性,比如微信就是需要安裝微信的app,而有些第三方登錄會跳轉到該第三方的登錄網站中,使用賬號密碼登錄。所以安全性方面需要看第三方了,像微信這樣的直接點擊確定登錄肯定沒有輸入第三方賬號密碼安全。綜合來講 第三方 登錄安全性不差,便捷性較高,另外不用注冊新的賬號密碼,在現在的登錄方式中非常普遍。

2.認證(Authentication)

首先普及兩個知識點:

a. 認證(Authentication)和授權(Authorization) 。借用別人的一個例子,你要登陸論壇,輸入用戶名張三,密碼1234,密碼正確,證明你張三確實是張三,這就是 authentication;再一check用戶張三是個版主,所以有權限加精刪別人帖,這就是 authorization。

b. token :token就是令牌的意思。為什么client中使用token代替cookie/session呢?token去掉了服務器端的狀態保持,擴展性更好,不需要在服務器進行存儲,只需要驗證就好。

(1)賬密認證

b1b31c5f-d4ad-44b4-ae2a-3092b2e5474a.png

Client指的是移動終端,Application指的是應用服務器。

賬密的認證很簡單,數據庫驗證下就行。

注意:密碼一般都會使用MD5進行hash下

(2)驗證碼認證

比賬號密碼多了步產生驗證碼的過程,并且匹配一般在緩存數據庫(如memcache或者redis)中進行,驗證是需要驗證過期時間。

(3)第三方認證

對于說使用友盟和shareSDK的同學,這篇文章不是講怎么做,而是表述一些我在APP登錄方面的一些見解,以及原理剖析。

為了描述清楚,使用微信作為代表(事先需要到各個迪桑放網站注冊自己的server Application)

步驟如下:

1.client點擊微信圖標登錄,帶上Application ID和scope,這些都是在你注冊Application的時候可以看到的

2.微信SDK會調用本地接口,打開微信的授權頁,如下:

3.點擊確定登錄,微信server驗證用戶,然后會redirect to 你的Application server,帶上code碼

4.code碼的有效期很短,需要立即使用code碼用API從微信server換取 access_token 等驗證數據

5.application獲取到token后就能將這些數據存儲到數據庫,(數據庫具體格式后面會有介紹)。并且通過 access_token 從微信server拿到用戶的一些基本信息,比如頭像,昵稱等等。

6.有些應用不允許單獨社交賬號存在,必須綁定手機號碼/密碼,因此對于不同的業務,不同的場景各自去做。這其實也是一大塊,手機號碼的綁定,解綁,注冊,第三方賬號的綁定解綁,綁定到另外的手機號,密碼找回,是否用手機號為主賬號,等等等等一系列的業務邏輯,各個公司各個產品因為安全性能要求和設計不同,表現形式也是多種多樣。在這里不做詳細的探討了,有興趣的同學可以自己去梳理梳理。

7.application server產生自己的 access_token ,返回給client,client進行用戶數據的訪問和API的調用。

關于微信的第三方登錄流程具體的可以去 微信開放平臺 中的->資源中心->移動應用->微信登錄功能。其他的平臺都差不多。

Client始終沒有拿到第三方的token,是因為client獲取第三方數據完全可以通過server中轉,這樣就避免將token暴露給Client,這樣第三方中用戶的數據也會更加安全

3.授權(Authorization)

對于不同的登錄方式會有不同的認證過程,但是授權就需要進行統一管理。

授權的關鍵點在于怎么產生一個好的access_token讓client進行數據訪問。oAuth2是一個很好的解決方案,JWT(JSON Web Token)是目前比較流行也比較安全的一種token產生和驗證機制。

當然也可以自己產生token,一般使用"時間戳+UserGuid+椒鹽噪聲"然后非對稱加密,傳輸給Client。JWT是一種更加規范,更加安全的Token的生成和校驗方式。

jwt

jwt規范

JWT的介紹看這里

授權過程:

(1)認證成功后,得到或者生成 UserGui d(用戶的唯一id碼,同一個賬戶的不同登錄方式擁有同一個 UserGuid ),然后通過JWT生成token,token中包含 UserGuid ,token過期時間等等。

(2)將JWT token傳送給client,client收到后保存下來。之后在向服務器請求數據時帶在Header上

(3)服務器收到client的請求,然后使用中間件進行JWT拆分,得到其中的token過期時間, UserId 以及其他一些Claims。根據其中的Claim進行身份校驗,這里不同的server有不同的操作。

注意:1.JWT token是明文傳輸的,可以通過 base64url_decode 獲得其中的Claims信息,因此不要將敏感信息放進去

2.JWT的安全:因為JWT的第三部分是通過HS256加密的,所以client不能夠通過Claims進行仿造token,這樣會導致在server校驗不通過。但是如果整個token被盜取了就沒有辦法了,畢竟這個tokn是所有請求權限的令牌。當然也可以通過在token中添加設備碼等信息進一步加強其安全性。

3.token過期刷新問題:如果server檢查到client的token過期,就會返回401錯誤。而一般的token設置有效期不長,總不能每次過期就重新登錄吧。有兩個解決方案。一是在在有效時間,比如在時間到達有效時間的3/4時,就開始向客戶端推送新的token,最極端的做法是每次請求都換token,這樣安全性高,但是太費server資源,并且在高并發情況下會有舊的請求被否決的情況。還有一種方案,就是在過期時間外再設定一個刷新時間期限的Claim,這個時間設定長一些,跟OAuth2中的 refresh_token 相似。當檢測到token過期時,查看刷新時間過期沒有,如果沒有過期,則重新生成JWT token返回給client。

4.server端數據庫設計

用戶登錄模塊在數據庫模塊也需要好好設計,不能因為每添加一種第三方認證就修改數據庫表。

(1)用戶基本信息表User

UserID avatar name ...
2 url1 name1 -
1 url2 name2 -
3 url3 name3 -

用戶基本信息表包含一些用戶基本信息,主鍵是用戶的 UserGuid ,是唯一的。

(2)用戶驗證表User_auths

primary UserID identity_type identify credential isFirstParty
1 2 email 12345@gmial.com MD5MD5MD5 True
2 2 account accountName accountPwMD5 True
3 1 phone 12345678909 pwMD5 True
4 2 wechat wechatID access_token & refresh_token False
5 3 weibo weiboID access_token & refresh_token False

用戶驗證表,包含用戶的各種登錄方式,對列名解釋: primaryKey :主鍵,唯一。 UserGuid :用戶唯一標識,在表中不唯一。 identity_type :登錄方式。 identify :該方式的賬戶名或ID。 isFirstParty :是否是第一方登錄。 credential :對于第一方是密碼,對于第三方是 access_token 和 refresh_token 。

很多現在的APP第三方登錄成功獲得用戶基本資料后便丟棄第三方的 access_token 和 refresh_token ,其實如果為了真正的安全,還是需要保存下來,每次自動登錄后通過第三方 access_token 和 refresh_token 來更新用戶信息以及驗證用戶是否是真實身份。

UserGuid 不唯一,可能有多個賬號對應同一個 UserGuid (第三方綁定到電話賬號等等)。使用 isFirstParty 來標注是否是第一方,對于有些應用email/phone/accout的密碼是同一個,修改的話就需要同時修改,需要通過標志位來定位這些第一方賬號。

 

來自:http://www.jianshu.com/p/c95c4741d725

 

 本文由用戶 mr4831 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!