最近看了看公司後臺用戶登陸系統的設計, 比較混亂, 主要仍是由於URS和Oauth以及URS第三方這三個登陸形式各不相同致使的。html
下面着重介紹一下涉及到第三方登陸中須要注意的問題數據庫
在一個新項目中, 若是是要創建本身的登陸體系的話, 那麼直接建立一個Users
表,包含username
和password
兩列,這樣,就能夠實現登陸了:架構
id | username | password | name等其餘字段 ----+----------+----------+---------------- A1 | bob | a1b23f2c | ... A2 | adam | c0932f32 | ...
若是要讓用戶經過第三方登陸,好比微博登陸或QQ登陸,怎麼集成進來呢?post
以微博登陸爲例,因爲微博使用OAuth2協議登陸,因此,一個登陸用戶會包含他的微博身份的ID,一個Access Token用於表明該用戶訪問微博的API和一個過時時間。spa
要集成微博登陸,不少童鞋馬上想到把Users
表擴展幾列,記錄下微博的信息:設計
id | username | password | weibo_id | weibo_access_token | weibo_expires | name等其餘字段 ----+----------+----------+----------+--------------------+---------------+---------------- A1 | bob | a1b23f2c | W-012345 | xxxxxxxxxx | 604800 | ... A2 | adam | c0932f32 | W-234567 | xxxxxxxxxx | 604800 | ...
加一個QQ登陸Users
表就又須要加3列,很是不靈活code
那麼咱們須要對這個表進行拆分。當用戶以任意一種方式登陸成功後,咱們讀取到的老是Users表對應的一行記錄,它其實是用戶的我的資料(Profile),而登陸過程只是爲了認證用戶(Authenticate),不管是本地用密碼驗證,仍是委託第三方登陸,這個過程本質上都是認證。htm
因此,若是把Profile和Authenticate分開,就十分容易理解了。Users表自己只存儲用戶的Profile, 其中ID爲關聯不一樣登陸方式的外鍵。blog
id | name | birth等其餘字段 ----+------+----------------- A1 | Bob | ... A2 | Adam | ...
而經過用戶名口令登陸可視爲一種Authenticate的方式,利用LocalAuth表維護:token
id | user_id | username | password ----+---------+----------+----------- 01 | A1 | bob | a1b23f2c 02 | A2 | adam | c0932f32
經過微博登陸可視爲另外一種Authenticate方式,利用OAuth表維護, 可是access_token通常狀況也只有幾個小時的時效, 因此存儲它是沒有意義的, 每次登陸的時候去微博後臺驗證一下客戶端傳來的token就好了。 若是用戶只用了第三方登陸, 那就拿第三方數據來填充剛纔的User表便可。
id | user_id | weibo_id | ----+---------+----------+ 11 | A1 | W-012345 | 12 | A2 | W-234567 |
若是要添加另外一種OAuth登陸,好比QQ登陸,那就再加一個列標示不一樣站點也就OK了, 可是要注意用戶在不一樣登陸方式的用戶名和photo通常不同, 因此也單獨存起來
id | user_id | oauth_name | oauth_id | nick_name| photo| ----+---------+------------+----------+----------+------+ 11 | A1 | weibo | W-012345 | 12 | A2 | weibo | W-234567 | 13 | A1 | qq | Q-090807 | 14 | A2 | qq | Q-807060 |
經過這種方式, 不管用戶採用哪一種方式登陸, 均可以鎖定到用戶的user_id。
下面再說一下網易的URS登陸, 由於咱們要直接採用網易通行證, 因此也就不需本身存儲密碼, 所以咱們的架構應該設爲User表
id | user_Email | username | birth ----+------------+----------+----------- 01 | aa@126.com | bob | 02 | bb@126.com | adam | 若是用戶只用第三方登陸, 顯然沒法填充user_Email這個字段, 所以userEmail能夠爲空。 若是第三方登陸採用的是URS第三方的接口, 它返回的oauth_id 是aa@wx.163.com這種形式。 具體設計和上面也相似。 總體上使用這種方式比如今後臺的邏輯要清晰不少