以前接入百度帳號系統的時候寫了一篇博客作研究:【大前端】認識單點登陸,出來後才發現,不少小公司其實並無將帳號系統打通,總結一下帳號系統沒通的緣由是:html
① 最初設計就沒想過身份認證應該作整合前端
② 後續業務中逐漸發現登錄系統過多,可是迫於業務壓力以及整合複雜度,因而再擱置web
這個就是技術債了,這種基礎服務的技術債不及時還,會致使不可忽視的工程問題:數據庫
① 帳號系統相關需求愈來愈多(登陸、註冊、我的信息管理......),每次都須要從新作跨域
② 用戶數據沒有一個收口的地方,若是數據量一塊兒來要整合、分析就難了(好比一些系統使用帳號登陸、一些系統使用手機登陸,若是想所有改形成以手機登陸就很難作到)服務器
③ 帳號系統不通(全部應用須要共享一個身份認證系統),會致使頻道不通問題,好比多數狀況下錢包也是一個獨立的頻道,而一個子頻道產生訂單後,須要去錢包頻道完成支付(http --> https)這個時候若是須要從新登陸的話是十分操蛋的行爲cookie
要解決以上問題,就要打通帳號系統,這個有兩個必要條件:session
① 全部應用系統都直接依賴與同一套身份認證系統dom
② 全部的子系統都得改造經過上述認證系統認證,也就是以前文章說的,要可以識別ticket數據庫設計
而後真實的狀況是比較失望的,以前已經有不少子系統各自爲政了,並且數據庫都不一致,因此更多的時候咱們的問題是:
① 如何實現打通帳號系統
② 新業務如何接入帳號系統
③ 老業務如何接入帳號系統
④ H5應該如何作
⑤ Native應該如何作
⑥ 沒時間(沒意識)
文中內容皆是自我知識總結,而且我是前端,若是文中有誤請您指出。
實現帳號系統打通的前提是用戶數據共享,分散的用戶管理是帳戶系統打通的攔路虎,用戶數據不能共用,各個系統之間根本沒任何聯繫,因此要嚴謹子業務獨立建立用戶,公司的全部系統必須依賴於同一張用戶信息表,這是一張不包含任何業務的表,可能包含如下數據:
① 用戶id
② 用戶暱稱
③ 用戶手機
④ 用戶密碼
⑤ 頭像&性別&出生年月&身份證&頭像......
比較差的狀況是各個子系統的登陸註冊徹底獨立,這樣用戶便造成了信息孤島,將各子系統的用戶公共信息遷移到一張表是第一步。
PS:這種各個子系統獨立的狀況,甚至可能出現用戶表中存在重複手機號的狀況
若是全部子系統接共用同一張用戶表,那麼第一個問題立刻就出來了,差別化如何處理,好比:
① 子系統A用戶具備角色權限功能,好比管理員、遊客、超級管理員
② 子系統B用戶用於醫院角色,具備職稱屬性,正教授、副教授、講師
③ 子系統C爲一個醫院機構,具備地址、三甲等屬性
這個時候須要各個子系統本身維護一個用戶角色表,好比這樣:
1 //用戶總表 2 //公司用戶不必定都是子系統的用戶,但子系統用戶必定存在與公司用戶總表中 3 var users = [ 4 { 5 id: '1', 6 phone: '13579246810', 7 name: '暱稱1', 8 infos: '其它公共信息' 9 }, 10 { 11 id: '2', 12 phone: '13579246811', 13 name: '暱稱2', 14 infos: '其它公共信息' 15 }, 16 { 17 id: '3', 18 phone: '13579246812', 19 name: '暱稱3', 20 infos: '其它公共信息' 21 } 22 ]; 23 //子系統A中的用戶表 24 var a_users = [ 25 { 26 id: '1', 27 roleId: '1'//遊客 28 }, 29 { 30 id: '3', 31 roleId: '2'//超級管理員 32 } 33 ]; 34 //子系統B中的用戶表 35 var b_users = [ 36 { 37 id: '1', 38 title: '教授'//遊客 39 }, 40 { 41 id: '2', 42 roleId: '副教授'//超級管理員 43 } 44 ]; 45 //子系統C中的用戶表 46 var c_users = [ 47 { 48 id: '2', 49 address: 'xxxx', 50 title: '三甲'//遊客 51 }, 52 { 53 id: '3', 54 address: 'xxxx', 55 roleId: '二甲'//超級管理員 56 } 57 ];
這個時候不一樣的系統差別化就能獲得處理。有一種比較很差的狀況是,以前子系統用戶表中就已經包含了業務信息好比(roleId),這個時候要分離就比較煩了
不少朋友不關注數據庫設計的三範式,但真正遇到問題的時候才能深入認識到第三範式能帶來什麼好處!
用戶數據打通後,即可在此基礎上進行下一步工做了!!!
全部的passport系統(統一登陸認證系統)核心功能就兩個:
① 登陸
② 受權或者鑑權
PS:由於咱們團隊暫時全部應用全在一個主域下,就暫時沒考慮跨域的狀況。
咱們這裏的實現方案是這樣的:
① 子系統(a.domain.com)訪問須要登陸的接口,未登陸則跳到統一登陸頁面(passport.domain.com)
② 用戶完成登陸後,server端向主域cookie寫入ticket,跳回子系統a.domain.com
③ 子系統a.domain.com訪問接口,server端發現帶有ticket,便去passport服務器校驗,成功則返回給子系統server用戶id
④ 子系統往本身域名寫入cookie,有效時間內再也不走passport鑑權
同理,若是子系統b.domain.com進行系統,由於主域上已經有ticket,便會直接進入a的業務系統,獲取和該業務系統相關的權限控制等信息了
這裏舉個例子,用戶調用獲取基本信息接口getInfo整個流程:
① 由於接口須要登陸狀態,因此先到passport登陸
② passport登陸後往主域cookie種入標誌ticket,而且從新跳回子系統
③ 子系統訪問getInfo接口,發現主域中具備ticket標誌,則拿着這個標誌去passport校驗,校驗成功返回用戶信息
④ 子系統根據基礎用戶信息,拿着用戶id將更多的信息篩選出來,好比roleId,返回給前端H5頁面
這個便是統一的認證系統,而這裏有一個容易被忽略的關鍵是:
子系統獲取主域中的ticket,去passport校驗有效性
這句話的意思是,每一個子系統都必須可以識別passport機制的ticket,意思是每一個子系統都必須接入passport
而接入的方式其實很簡單,幾個步驟就能夠作完,好比說:
① passport方提供一個接口,getUserInfo,若是主域中具備cookie信息便能返回用戶信息,若是沒有就返回錯誤碼(未登陸)
② 業務系統若是須要登陸信息的話,server首次直接根據ticket去passport拿用戶信息,若是拿獲得就在本地存儲session,若是拿不到就直接返回passport的錯誤碼便可
③ 業務系統若是拿到用戶信息,能夠本身作簡單包裝,也能夠什麼都不作,全看業務需求
關於退出登陸,其實比較簡單,稍微改下各個業務系統的判斷規則,必須ticket在才考慮自己系統的session是否存在,每次退出操做,直接調用passport的登出接口刪除主域ticket便可。
更多狀況下咱們會有APP使用Webview打開H5頁面的狀況,這裏要作登陸態處理的話,便須要App請求passport接口後保存ticket,當打開webview時直接往主域注入ticket便可。
固然,這裏的前提是,子系統已經接入了passport。
關於跨域部分由於實際工做沒有碰到暫時不涉及,這裏知識點根據後續接入程度可能會作修改。
關於代碼的簡單實現你們能夠看看這篇文章:http://www.cnblogs.com/yexiaochai/p/4422460.html實現大同小異