支持多種登錄方式的數據庫設計


  一個帶有用戶系統的應用最基本登錄方式是站內賬號登錄,但這種方式往往不能滿足我們的需求。現在的應用基本都有站內賬號、email、手機和一堆第三方登錄,那么如果需要支持這么多種登錄方式,或者還有銀行卡登錄、身份證登錄等等更多的登錄方式,我們的數據表應該怎么設計才更合理呢?

  首先,一個用戶不管有多少種登錄方式,用戶還是只有那一個用戶,但登錄方式卻有多種。這就形成了一對多的關系:一個用戶對應多個登錄方式。
  所以,我們就可以把用戶表拆分成2張表,一張表存儲用戶基本的數據,另一張表存儲登錄授權相關的數據。我們可以向下面這樣設計:

  用戶表【USERS】:

主鍵【ID】

用戶名【USERNAME】

性別【GENDER】

年齡【AGE】

電話【PHONE】

狀態【STATUS】

  授權表【USER_AUTHS】:

主鍵【ID】

用戶外鍵【USERID】:用戶表對應的主鍵;

登錄類型【IDENTITYTYPE】:登錄類別,如:系統用戶、郵箱、手機,或者第三方的QQ、微信、微博;

識別標識【IDENTIFIER】:身份唯一標識,如:登錄賬號、郵箱地址、手機號碼、QQ號碼、微信號、微博號;

授權憑證【CREDENTIAL】:站內賬號是密碼、第三方登錄是Token;

是否驗證【IFVERIFIED】:授權賬號是否被驗證;

  這樣我們創建一個用戶,首先需要創建一條用戶表的用戶基礎信息記錄和一條或者多條授權表的授權記錄。注意修改密碼時也需要同時修改多條授權表記錄,保證需要密碼的登錄方式憑證需要同步更新。

用戶表
ID USERNAME GENDER AGE PHONE STATUS
1   LUCY FEMALE 18 138----- 有效

 

 

 

授權表
ID USERID IDENTITYTYPE IDENTIFIER CREDENTIAL IFVERIFIED
1 1 系統用戶 test 888888 YES
2 1 郵箱 *@QQ.COM 888888 YES
3 1 手機 138--------- 888888 YES
4 1 微信 138******** token值 YES
5 1 微博 weiboID token值 YES

 

 

 

 

 

 

 

  說說具體處理,用戶發來郵箱/用戶名/手機號和密碼請求登錄的時候,依然是先判斷類型,以某用戶使用了手機號登錄為例,使用 SELECT * FROM USER_AUTHS WHERE IDENTITYTYPE='手機' AND IDENTIFIER='手機號' 查找條目。如有,則取出並判斷密碼是否和該條目的CREDENTIAL相符,相符則通過驗證,隨后通過USERID獲取用戶信息。

  如果使用第三方登錄,則只要判斷 SELECT * FROM USER_AUTHS WHERE IDENTITYTYPE='微信' and IDENTIFIER='微信號'。如果有記錄,則直接登錄成功,使用新的token更新原token。假設與微信服務器通信不被劫持的情況下無需判斷憑證問題。

  通過這種表結構設計,使許多原來糾結的問題瞬間解決。

  優點:

  1、站內登錄類型無限拓展,代碼改動小。如果真要支持身份證登錄了,只要少許幾處改動,無需修改表結構。

  2、第三方登錄類型可用工場模式批量拓展,新增第三方登錄類型的開發成本降到最低。

  3、在USER_AUTHS表中增加一個統一的verified字段,每種登錄方式都可以直觀看到是否已驗證情況。基於信任第三方登錄的數據准確性,默認第三方登錄都是已驗證。如果用戶修改登錄手機號或登錄郵箱,也能清晰跟蹤每一步的完成度。

  4、可按需綁定任意數量的同類型登錄方式,即一個用戶可以綁定多個微信,可以有多個郵箱,可以有多個手機號,是不是很贊!當然你也可以限制一種登錄方式只有一條記錄。

  5、在USER_AUTHS添加相應的時間和IP地址,就可以更加完整地跟蹤用戶的使用習慣(此部分應該單獨建立日志表)。比如,已經不使用微博登錄兩年多,已經綁定微信300天。

  6、即使完全使用第三方帳號登錄,可在前端做到“無需注冊本站帳號”的效果。過去許多網站雖然支持第三方帳號登錄,但出於留存用戶等原因,第一次微博登錄回來,讓你再填寫一套他們網站的郵箱、密碼等信息,也就失去了微博登錄的最大意義。

  從技術上說,原有的結構導致除了在微博用戶表建立一個條目外,必須在用戶表建立一條對應的條目,而且一般情況下不能讓用戶表里的郵箱或者用戶名和密碼留空。用戶體驗好的,郵箱自動生成 微博ID@id.weibo.sina.com ,密碼則隨機生成。至於體驗不好的,只能說早知道還不如不用微博登錄呢!現在呢,我們的這個用戶表結構則完全沒有這樣的困擾,只要微博提供的昵稱和頭像地址就可以生成這個用戶,再關聯他的微博登錄記錄。而且我們的表結構意味着,用戶可以解除他的所有登錄方式,於是這個賬戶便徹底變成了沒法登錄的僵屍(解決辦法是在代碼里加一個限制,至少保留一條USER_AUTHS的記錄)。如果你非要得到用戶的郵箱,那么每次登錄的時候看到他不存在一條IDENTITYTYPE為email的記錄,則彈窗彈死他,讓他趕快填郵箱,否則啥都別干。

  7、提升了邏輯思維能力。抽象出事物本質是碼農必備職業素養。

  8、如果你說郵箱和手機號就是用戶信息的組成部分,他們依然需要體現在USERS表中作為前端展示。USERS表盡管拓展,USERS表里依然有email,phone。但它們僅僅作為“展示用途”,這和昵稱、頭像、或者性別這些屬性沒有本質區別。在用戶信息表與用戶授權登錄拆分后,用戶信息表可以隨時增加任意字段,加星座,加生日,都沒問題,只需要在前端展示時多幾個輸入框,錄入時多幾行代碼,與用戶登錄相關的問題做到最大程度解耦。

  缺點:

  1、原先的用戶判斷由1次SQL變成2次SQL請求。
  2、用戶同時存在郵箱、用戶名、手機號等多種站內登錄方式時,改密碼時必須一起改,否則就變成了郵箱+新密碼,手機號+舊密碼訪問了,肯定是很詭異的情況。如果考慮到這一點,又要在USER_AUTHS表中新增一個表示站內登錄方式或第三方登錄方式的標識字段。
  3、代碼量增加了,有些情況下邏輯判斷增加了,難度增大了。

  舉個例子,無論用戶是否已登錄,無論用戶是否已注冊過,都是點擊同一鏈接前往微博第三方授權后返回,可能出現幾種情況:

  1)該微博在本站未注冊過,很好,直接給他注冊關聯並登錄;

  2)該微博已經在本站存在,當前用戶未登錄,直接登錄成功;

  3)該微博未在本站注冊,但當前用戶已經登錄並關聯的是另一個微博帳號,作何處理取決於是否允許綁定多個微博帳號;

  4)該微博未在本站注冊過,當前用戶已登錄,嘗試進行綁定操作;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM