1、實現簡單Web-SSO之總述

目錄

1、總述
2、環境配置
[3、業務servers管理]
[4、用戶信息同步]
[5、token的攔截、生成、驗證(服務端)]
[6、概念辨析:session、cookie、token的區別與token存儲]
[7、token的分享(瀏覽器端)]
[8、安全性措施]
[9、用戶體驗]
[10、性能]前端


關於沒有後續更新的問題

各位,實在抱歉!SSO本來是個人畢業設計,可是出於某個緣由,我決定留級,畢設暫時擱淺!這段時間忙着準備面試的事情,系統學習前端中ing! 這是這個系列被擱淺的緣由之一!另外一個緣由在於,我發現沒有經歷過企業開發,真的在某些環節上很難理解SSO中一些讓我很是困惑的問題!好比,我一直困惑的這個問題,這很是有多是一個很簡單的問題,可是我每每是被這種問題困惑住。好比,「性能」問題,大四實習年一直沒在IT企業,討論「性能」內心很虛,我更想接觸必定的開發以後,內心更加有底的寫下問題的答案。沒出問題的話,這個系列會在6月中旬繼續更新,但願8月能搞定。node


經商之道

今天我要講兩個故事,一家高級商場的故事和一家普通商場的故事。python

1.高級商場的故事

從前有個老闆叫C/S,他開了這樣一家高級商場叫「TCP/IP Server"。專門服務註冊了VIP的顧客。他們對待註冊了VIP的顧客的服務很是的高級。怎樣高級?每一位VIP顧客進來購物,就會有一個服務員全程陪同。這些服務員提供全部的服務,很是的有才能。但就是都很沒有記性,永遠都記不住本身是在服務哪位顧客。這也怪不得服務員,誰叫每一個VIP顧客都長得如出一轍呢?因而老闆就讓服務員全程牽着顧客的手,而且手裏拿着一張紙條,紙條上面寫着顧客的姓名、性別、年齡、餘額等等信息。這樣他們就能叫出顧客的尊稱,並且由於牽着手,因此不至於跟顧客走丟。真爲這一羣奇葩着急啊ヽ( ̄д ̄;)ノ!!!這些服務員這一羣體被學術家們稱爲「progress」,而顧客這一羣體被學術家們稱爲「client」web

我很好奇高級商場賣的都是些什麼東西。從商業角度來講,全程一對一的服務成本可真高啊。面試

2.普通商場的故事

後來,有一個老闆叫B/S,他以爲C/S是個傻X,全程一對一的服務成本高,收益小。因而他開了一家普通的商場叫"HTTP Server"。跟"TCP/IP Server"商場同樣,他的"HTTP Server"也是須要註冊VIP的。可是他的服務員們並不會全程陪同顧客購物。總的來講,他們提供兩樣服務:1.詢問 2.收銀。每一個服務員在處理完某個顧客的詢問服務或者收銀服務後,就能夠爲另外一個顧客服務。"B/S"覺得它的商場會比那個沒頭腦的「C/S」的商場收益更好!很顯然嘛,同樣多的服務員,他的店能服務更多的顧客。數據庫

天真的B/S,可憐的B/S。他差點就破產了~ 還不是那羣讓人着急的服務員!開張第一天,他們就惹來了滿滿的差評。他們老是記不住顧客買了什麼東西,根本沒有辦法收銀;並且顧客上前要詢問他們「node.js的產品在哪一個貨架?」、「Python有多少種框架產品?」等問題的時候,這羣服務員老是沒有辦法先叫出顧客的名字來給予顧客問候。顧客以爲他們都很沒有禮貌~~~這也怪不得服務員,健忘是他們的天性,更況且每一個顧客的相貌、穿着、聲音又都徹底同樣,他們但是要一我的服務多個顧客的!express

B/S決定關店整改!!!他給每一個服務員配備了一個記錄器。有一個服務員專門負責把進店的會員信息寫進記錄器,而後把一串惟一的ID寫在一種叫作cookie的紙上,把紙貼在顧客額頭上......沒錯,貼在額頭上。其它服務員只要往記錄器輸入顧客頭上的ID,就能查詢到顧客的信息,這樣服務員就不會由於叫不出顧客的名字被說沒禮貌了;而且能夠把顧客要買的東西,臨時的記錄在記錄器裏面。固然啦,記錄器裏的記錄是整個商場共享的。因此,即使顧客A買《黑客與畫家》的時候是服務員A給記錄的,買《寫給你們看的設計書》的時候是服務員B給記錄的,結算的時候又是服務員C,他們搞錯了。 B/S很是自豪的把這種記錄器機制叫作session機制,真搞不懂他爲何要這麼叫。就這樣,B/S「HTTP Server」商場以更低的成本得到了更大的收益~ 他發跡了。segmentfault

登陸這件事

登陸就是經過驗證(密碼驗證、指紋驗證、聲音驗證、人面驗證、DNA驗證...),向服務端代表你是誰?而且讓服務端記住你是誰。對於C/S的架構來講,要記住你是誰太容易了~ 客戶端跟服務端創建的TCP/IP鏈接就能很好的代表你誰,一個進程服務一個客戶端,只要在進程空間裏寫個變量就OK了!可是對於B/S架構來講,由於是無狀態的,服務一結束就斷開(如今的長鏈接也仍是會斷),要記住你是誰真心太不容易了~ 因此只能由客戶端來告訴服務端:「我是誰。」,也就是給客戶端一個ID,而後服務端有個全局的空間(session)用於記錄ID對於的信息,相似於Map<ID, infomations>。對於每一次的服務請求,服務端都要拿着客戶端給的ID,去session查詢這個ID是否是登陸了,若是是則怎樣怎樣,若是不是就叫用戶登陸(假設每一個頁面的訪問都要求用戶登陸)。拿着ID去session查詢ID是否是登陸了這個過程咱們把它叫作檢驗,這點先提早說明下,有點重要!登陸成功後,就把這個ID作一個標記,表示登陸。什麼樣的標記?你能夠在這個ID的session空間裏設置一個變量叫mark用來表示登陸了,可是不會有人這麼作的,至少也得設置個username的變量。否則你怎麼知道這個用戶是哪個用戶呢?有username就能夠再去數據庫查詢更多的信息,固然也能夠把更多的信息寫到session裏面,這裏不作討論。跨域

什麼是單點登陸(Single Sign-On)

很早期的公司,一家公司可能只有一個Server,慢慢的Server開始變多了。每一個Server都要進行註冊登陸,退出的時候又要一個個退出。用戶體驗很很差!你能夠想象一下,上豆瓣 要登陸豆瓣FM、豆瓣讀書、豆瓣電影、豆瓣日記......真的會讓人崩潰的。咱們想要另外一種登陸體驗:一家企業下的服務只要一次註冊,登陸的時候只要一次登陸,退出的時候只要一次退出。怎麼作?瀏覽器

一次註冊。 一次註冊不難,想一下是否是隻要Server之間同步用戶信息就好了?能夠,但這樣描述不太完整,後續講用戶註冊的時候詳細說。實際上用戶信息的管理纔是SSO真正的難點,只是做爲初學者,咱們的難點在於實現SSO的技術!咱們先討論實現手段。

一次登陸與一次退出。 回頭看看普通商場的故事,什麼東西纔是保持登陸狀態關鍵的東西?記錄器(session)?那種叫作cookie的紙張?寫在紙張上的ID? 是session裏面記錄的信息跟那個ID,cookie只不是記錄ID的工具而已。客戶端持有ID,服務端持有session,二者一塊兒用來保持登陸狀態。客戶端須要用ID來做爲憑證,而服務端須要用session來驗證ID的有效性(ID可能過時、可能根本就是僞造的找不到對於的信息、ID下對應的客戶端尚未進行登陸驗證等)。可是session這東西一開始是每一個server本身獨有的,豆瓣FM有本身的session、豆瓣讀書有本身的session,而記錄ID的cookie又是不能跨域的。因此,咱們要實現一次登陸一次退出,只須要想辦法讓各個server的共用一個session的信息,讓客戶端在各個域名下都能持有這個ID就行了。再進一步講,只要各個server拿到同一個ID,都能有辦法檢驗出ID的有效性、而且能獲得ID對應的用戶信息就好了,也就是能檢驗ID

單點登陸的實現方法(server端)

以server羣如何生成、驗證ID的方式大體分爲兩種:

  • 「共享Cookie」
    這個就是上面提到的共享session的方式,我倒以爲叫「共享session」來得好一點,本質上cookie只是存儲session-id的介質,session-id也能夠放在每一次請求的url裏。聽說這種方式不安全,我沒去細究,哪位大神能夠推薦下相關的資料,我後期補上。其實也是,畢竟session這項機制一開始就是一個server一個session的,把session拿出來讓全部server共享確實有點奇怪。

  • SSO-Token方式
    由於共享session的方式不安全,因此咱們再也不以session-id做爲身份的標識。咱們另外生成一種標識,把它取名SSO-Token(或Ticket),這種標識是整個server羣惟一的,而且全部server羣都能驗證這個token,同時能拿到token背後表明的用戶的信息。咱們要討論的也是這種方式,一會上具體流程圖。

單點登陸的實現方法(瀏覽器端)

單點登陸還有很是關鍵的一步,這一步跟server端驗證token的方式無關,用最先的「共享session」的方式仍是如今的「token」方式,身份標識到了瀏覽器端都要面臨這樣的一個問題:用戶登陸成功拿到token(或者是session-id)後怎麼讓瀏覽器存儲和分享到其它域名下?同域名很簡單,把token存在cookie裏,把cookie的路徑設置成頂級域名下,這樣全部子域都能讀取cookie中的token。這就是共享cookie的方式(這才叫共享Cookie嘛,上面那個應該叫共享session)。好比:谷歌公司,google.com是他的頂級域名,郵箱服務的mail.google.com和地圖服務的map.google.com都是它的子域。可是,跨域的時候怎麼辦?谷歌公司還有一個域名,youtube.com,提供視頻服務。如何把身份標識分享給youtube.com這個域?簡單的先提下,後續會細說。

  • 利用帶有src屬性的HTML標籤跨域設置cookie。例如:

    <iframe width = 0 height=0 src="youtube.com/set_sso_token?ssotoken=iurk2i3f">
  • url跳轉。好比:在google.com登陸後,會跳轉到youtube.com下種植cookie,再跳轉會google.com。

  • Ajax設置cookie(目前還不瞭解,聽說京東是這麼作的。)

SSO-Token方式的服務端流程

實際上,基本是用Token代替session的方式,也有很是多種實現方法。圖片是我先去本身實驗時的方案。

圖片描述

SSO-Server負責用戶的登陸(固然也有註冊、修改基本用戶信息、退出功能),它的做用有兩點:

  • 驗證用戶。就是驗證帳號密碼。咱們略過不關注

  • 生成惟一的token

  • 往其它業務Server同步token等信息,讓各個業務server本身驗證token有效性(如圖); 或者,提供檢驗token有效性的API接口

咱們要實現什麼樣的SSO

  • token生成與驗證方案:如上圖。

  • token在瀏覽器的跨域分享方法,都嘗試一遍。

  • 安全性。暫時一概不考慮,咱們先關注實現一個差勁的SSO,再來關注安全。由於安全是個大話題。太早引入,太拖節奏

  • 實現語言:node.js(express4.x)。其實感受SSO的實現是語言無關的,一個node.js實現的登陸server徹底能夠爲一個python實現的業務server服務。server之間的關係最後都演化成web接口的調用。

相關文章
相關標籤/搜索