日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

浅谈数据库用户表结构设计和第三方登录

發(fā)布時(shí)間:2023/12/20 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈数据库用户表结构设计和第三方登录 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說(shuō)起用戶表 , 大概是每個(gè)應(yīng)用/網(wǎng)站立項(xiàng)動(dòng)工考慮的第一件事情 ; 用戶表結(jié)構(gòu)的設(shè)計(jì) , 算是整個(gè)后臺(tái)架構(gòu)的基石 ; 如果基石不穩(wěn) , 待到后面需求跟進(jìn)了發(fā)現(xiàn)不能應(yīng)付 , 回過(guò)頭來(lái)反復(fù)修改用戶表 , 要大大小小作改動(dòng)的地方也不少 ; 與其如此 , 不妨設(shè)計(jì)用戶表之初就考慮可拓展性 , 爭(zhēng)取不需要太多額外代價(jià)的情況下一步到位 ;

先前設(shè)計(jì)

id username password

用戶名加上密碼 , 解決簡(jiǎn)單需求 , 留個(gè) ID 作為其他表的外鍵 ; 當(dāng)然 , 那時(shí)候密碼還可能是明文存儲(chǔ) , 好點(diǎn)的知道 MD5 ;

后來(lái)呢 , 隨著業(yè)務(wù)需求的拓展 , 要加個(gè)用戶狀態(tài) status 判斷用戶是否被封禁 , 注冊(cè)時(shí)間和注冊(cè) IP 地址 , 上次登錄時(shí)間和 IP 地址備查 (并衍生出登錄記錄表 , 用來(lái)判斷是否異地登錄等 , 在此不表) , 用戶角色/權(quán)限 role (又衍生出用戶角色權(quán)限關(guān)系 , 還是另文討論) , 業(yè)務(wù)也需要個(gè)人的個(gè)人信息如真實(shí)姓名 , 地址等也一股腦往上添加 , 現(xiàn)在形成了一個(gè)很完整的用戶關(guān)系表 ;

id username password realname address … status role register_time register_ip login_time login_ip

現(xiàn)在問(wèn)題來(lái)了 , 進(jìn)入 Web2.0 時(shí)代 , 微博開(kāi)放了第三方網(wǎng)站登錄 , 用微博帳號(hào)就能登錄我們的網(wǎng)站 , 老板說(shuō) , 這個(gè)我們得要 , 加個(gè)微博用戶登錄表吧 , 當(dāng)然 , 得和我們自己的用戶表關(guān)聯(lián) , 這個(gè)微博用戶信息表如下 :

id 自增 ID user_id 關(guān)聯(lián)本站用戶 ID uid 微博唯一 ID access_token access_expire

這還不算完 , QQ又開(kāi)放用戶登錄了 , 一下子要接入好多家第三方登錄了 , 只能就著 “微博用戶信息表” 繼續(xù)加類型加判斷 , 如果是每個(gè)第三方登錄都新建一個(gè)表 , 肯定會(huì)瘋的 ;
時(shí)代變了 , 進(jìn)入了移動(dòng)互聯(lián)網(wǎng)時(shí)代 , 怎么也得支持個(gè)手機(jī)號(hào)登錄吧 , 所以現(xiàn)在每家標(biāo)配都是 : 用戶名/郵箱/手機(jī)號(hào) 登錄 , 外加一系列微博 , 微信等第三方登錄 , 表結(jié)構(gòu)如下 :

用戶表

id username email phone …

用戶第三方登錄表

id user_id app_type app_user_id access_token …

用戶在輸入框輸入 用戶名/郵箱/手機(jī)號(hào)和密碼 之后 , 后臺(tái)判斷是郵箱 , 手機(jī)號(hào)或是用戶名 , 再根據(jù)條件查詢是否為特定用戶 ;
這個(gè)表結(jié)構(gòu)能夠承載未來(lái)一段時(shí)間的業(yè)務(wù)需求了 , 如果說(shuō)某天冒出了一個(gè)新的登錄方式 , 比如身份證號(hào)登錄 , 怎么辦 ? 繼續(xù)在用戶表加字段 ? 我覺(jué)得有更好的選擇 ;

改進(jìn)版

無(wú)論 username + password , 還是 phone + password , 都是一種 用戶信息+密碼 的驗(yàn)證形式;再來(lái)理解第三方登錄 , 其實(shí)它也是用戶信息+密碼的形式 , 用戶信息即第三方系統(tǒng)中的 ID (第三方登錄一定會(huì)給一個(gè)在他們系統(tǒng)中的唯一標(biāo)識(shí)) , 密碼即 access_token , 只不過(guò)是一種有使用時(shí)效定期修改的密碼 ; 所以我們把它抽象出了用戶基礎(chǔ)信息表加上用戶授權(quán)信息表的形式 ;

用戶基礎(chǔ)信息表 users

id nickname avatar

用戶授權(quán)信息表 user_auths

id user_id identity_type 登錄類型 (手機(jī)號(hào)/郵箱/用戶名) 或第三方應(yīng)用名稱 (微信 , 微博等) identifier 標(biāo)識(shí) (手機(jī)號(hào)/郵箱/用戶名或第三方應(yīng)用的唯一標(biāo)識(shí)) credential 密碼憑證 (站內(nèi)的保存密碼 , 站外的不保存或保存 token)

這個(gè)系統(tǒng)最大的特色就是 , 用戶信息表不保存任何密碼 , 不保存任何登錄信息 (如用戶名 , 手機(jī)號(hào) , 郵箱) , 只留有昵稱 , 頭像等基礎(chǔ)信息 ; 所有和授權(quán)相關(guān) (且基本前端展示無(wú)關(guān)的) , 都放在用戶信息授權(quán)表 , 用戶信息表和用戶授權(quán)表是一對(duì)多的關(guān)系 ; 說(shuō)起來(lái)太抽象 , 表現(xiàn)如下 :

users

|id|nickname|avatar| |1|慕容雪村|http://…/avatar.jpg| |2|魔力鳥|http://…/avatar2.jpg| |3|科比|http://…/avatar3.jpg|

user_auths

|id|user_id|identity_type|identifier|credential| |1|1|email|123@example.com|password_hash(密碼)| |2|1|phone|13888888888|password_hash(密碼)| |3|1|weibo|微博UID|微博access_token| |4|2|username|moliniao|password_hash(密碼)| |5|3|weixin|微信UserName|微信token|

說(shuō)說(shuō)具體處理 , 用戶發(fā)來(lái) 郵箱/用戶名/手機(jī)號(hào)和密碼 請(qǐng)求登錄的時(shí)候 , 依然是先判斷類型 , 以某用戶使用了手機(jī)號(hào)登錄為例 , 使用 select * from user_auths where type= 'phone' and identifier= '手機(jī)號(hào)' 查找條目 , 如有 , 取出并判斷 password_hash (密碼)是否和該條目的 credential 相符 , 相符則通過(guò)驗(yàn)證 , 隨后通過(guò) user_id 獲取用戶信息 ;
如果使用第三方登錄 , 則只要判斷 select * from user_auths where type= 'weixin' and identifier= '微信UserName' , 如果有記錄 , 則直接登錄成功 , 使用新的 token 更新原 token ; 假設(shè)與微信服務(wù)器通信不被劫持的情況下無(wú)需判斷憑證問(wèn)題 ;

優(yōu)缺點(diǎn)

通過(guò)這個(gè)表結(jié)構(gòu)設(shè)計(jì) , 使許多原來(lái)糾結(jié)的問(wèn)題瞬間解決 , 說(shuō)說(shuō)優(yōu)點(diǎn) :

  • 站內(nèi)登錄類型無(wú)限拓展 , 代碼改動(dòng)小 ; 如果真要支持身份證登錄了 , 只要少許幾處改動(dòng) , 無(wú)需修改表結(jié)構(gòu) ;
  • 第三方登錄類型可用工場(chǎng)模式批量拓展 , 新增第三方登錄類型的開(kāi)發(fā)成本降到最低 ;
  • 原來(lái)?xiàng)l件下 , 應(yīng)用需要驗(yàn)證手機(jī)號(hào)是否已驗(yàn)證和郵箱是否已驗(yàn)證 , 需要相對(duì)應(yīng)多一個(gè)字段如 phone_verified 和 email_verified , 如今只要在 user_auths 表中增加一個(gè)統(tǒng)一的 verified 字段 , 每種登錄方式都可以直觀看到是否已驗(yàn)證情況 ; 基于信任第三方登錄的數(shù)據(jù)準(zhǔn)確性 , 默認(rèn)第三方登錄都是已驗(yàn)證 ; 如果用戶修改登錄手機(jī)號(hào)或登錄郵箱 , 也能清晰跟蹤每一步的完成度 ;
  • 可按需綁定任意數(shù)量的同類型登錄方式 , 即一個(gè)用戶可以綁定多個(gè)微信 , 可以有多個(gè)郵箱 , 可以有多個(gè)手機(jī)號(hào) , 是不是很贊 ? 當(dāng)然你也可以限制一種登錄方式只有一條記錄 ;
  • 在 user_auths 添加相應(yīng)的時(shí)間和 IP 地址 , 就可以更加完整地跟蹤用戶的使用習(xí)慣 , 比如 , 已經(jīng)不使用微博登錄兩年多 , 已經(jīng)綁定微信 300 天
  • 即使完全使用第三方帳號(hào)登錄 , 可在前端做到 “無(wú)需注冊(cè)本站帳號(hào)” 的效果 ; 過(guò)去許多網(wǎng)站雖然支持第三方帳號(hào)登錄 , 但出于留存用戶等原因 , 第一次微博登錄回來(lái) , 讓你再填寫一套他們網(wǎng)站的郵箱 , 密碼等信息 , 也就失去了微博登錄的最大意義 ; 從技術(shù)上說(shuō) , 原有的結(jié)構(gòu)導(dǎo)致除了在微博用戶表建立一個(gè)條目外 , 必須在用戶表建立一條對(duì)應(yīng)的條目 , 而且一般情況下不能讓用戶表里的郵箱或者用戶名和密碼留空 ; 用戶體驗(yàn)好的 , 郵箱自動(dòng)生成微博ID@id.weibo.sina.com , 密碼則隨機(jī)生成 ; 至于體驗(yàn)不好的 , 只能說(shuō)早知道還不如不用微博登錄呢 ! 現(xiàn)在呢 , 我們的這個(gè)用戶表結(jié)構(gòu)則完全沒(méi)有這樣的困擾 , 只要微博提供的昵稱和頭像地址就可以生成這個(gè)用戶 , 再關(guān)聯(lián)他的微博登錄記錄 ; 而且我們的表結(jié)構(gòu)意味著 , 用戶可以解除他的所有登錄方式 , 于是這個(gè)賬戶變徹底變成了沒(méi)法登錄的僵尸 (解決辦法是在代碼里加一個(gè)限制 , 至少保留一條user_auths的記錄) ; 如果你非得得到用戶的郵箱 , 那么每次登錄的時(shí)候看到他不存在一條 identify_type 為 email 的記錄 , 則彈窗彈死他 , 讓他趕快填郵箱 , 否則啥都別干 ;
  • 提升了邏輯思維能力 , 抽象出事物本質(zhì)是碼農(nóng)必備職業(yè)素養(yǎng) , 通過(guò)對(duì)用戶表結(jié)構(gòu)的學(xué)習(xí)研究 , 提高了鄙人的各方面技能 , 從此寫代碼一路順風(fēng)順?biāo)?/li>
  • 如果你說(shuō)郵箱和手機(jī)號(hào)就是用戶信息的組成部分 , 他們依然需要體現(xiàn)在 users 表中作為前端展示?沒(méi)問(wèn)題 , users 表盡管拓展 , users 表里依然有email , phone , 但他們僅僅作為 “展示用途” , 和昵稱 , 頭像 , 或者性別這些屬性沒(méi)有本質(zhì)區(qū)別 ; 在用戶信息表與用戶授權(quán)登錄拆分后 , 用戶信息表可以隨時(shí)增加任意字段 , 加星座 , 加生日 , 都沒(méi)問(wèn)題 , 只需要在前端展示時(shí)多幾個(gè)輸入框 , 錄入時(shí)多幾行代碼 , 與用戶登錄相關(guān)的問(wèn)題做到最大程度解耦 ;

有利必有弊 , 說(shuō)說(shuō)缺點(diǎn) :

  • 原先的用戶判斷由 1 次 SQL 變成 2 次 SQL 請(qǐng)求 ;
  • 用戶同時(shí)存在郵箱 , 用戶名 , 手機(jī)號(hào)等多種站內(nèi)登錄方式時(shí) , 改密碼時(shí)必須一起改 , 否則就變成了 郵箱 + 新密碼 , 手機(jī)號(hào) + 舊密碼 訪問(wèn)了 , 肯定是很詭異的情況 ; 如果考慮到這一點(diǎn) , 又要在 user_auths 表中新增一個(gè)表示站內(nèi)登錄方式或第三方登錄方式的標(biāo)識(shí)字段 ;
  • 代碼量增加了 , 有些情況下邏輯判斷增加了 , 難度增大了 ; 舉個(gè)例子 , 無(wú)論用戶是否已登錄 , 無(wú)論用戶是否已注冊(cè)過(guò) , 都是點(diǎn)擊同一鏈接前往微博第三方授權(quán)后返回 , 可能出現(xiàn)幾種情況 : 1 , 該微博在本站未注冊(cè)過(guò) , 很好 , 直接給他注冊(cè)關(guān)聯(lián)并登錄;2 , 該微博已經(jīng)在本站存在 , 當(dāng)前用戶未登錄 , 直接登錄成功;3 , 該微博未在本站注冊(cè) , 但當(dāng)前用戶已經(jīng)登錄并關(guān)聯(lián)的是另一個(gè)微博帳號(hào) , 作何處理取決于是否允許綁定多個(gè)微博帳號(hào);4 , 該微博未在本站注冊(cè)過(guò) , 當(dāng)前用戶已登錄 , 嘗試進(jìn)行綁定操作;5 , 該微博已經(jīng)注冊(cè) , 用戶又已使用該帳號(hào)登錄 , 為何他重復(fù)綁定自己 ; 6 , 該微博已經(jīng)在本站存在 , 但當(dāng)前用戶已經(jīng)登錄并關(guān)聯(lián)的是另一個(gè)微博帳號(hào) , 作何處理 ? 切換用戶或是報(bào)錯(cuò) ? (畫一個(gè)流程圖能更好描述這個(gè)問(wèn)題) 這個(gè)問(wèn)題與采用的數(shù)據(jù)結(jié)構(gòu)沒(méi)有關(guān)系 , 只是在做第三方帳號(hào)注冊(cè)登錄時(shí)遇到的各種情況 , 在此一并整理 ;

作者 Github : tojohnonly , 博客 : EnskDeCode

總結(jié)

以上是生活随笔為你收集整理的浅谈数据库用户表结构设计和第三方登录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。