剛剛,給學妹普及了登入的兩大絕學

2022-01-09 23:09:11 字數 3520 閱讀 5712

今天跟大家聊乙個比較基礎的話題,就是實現登入的方式有哪些?適合剛入行的朋友。

session 我們稱之為會話控制, 是一種在伺服器端保持會話狀態的解決方案。通俗點來講就是客戶端訪問服務端的時候,會在服務端儲存對應的資訊,生成乙個 session id 返回給客戶端,客戶端下次過來的時候帶上 session id,這樣就能識別訪問者的身份。

請求中帶上 session id 最常見的方式就是通過 cookie 來承載了,cookie 是客戶端儲存使用者資訊的一種機制,在瀏覽器環境中,請求會自動帶上 cookie 資訊,服務端也就能獲取到 session id。

在後端實現登入邏輯的時候,先獲取 httpsession 物件,然後通過 setattribute()來設定登入的使用者資訊,比如使用者 id。驗證有沒有登入的時候通過 getattribute()來獲取對應的 session 資訊,如果沒有獲取到,則證明沒有登入過或者會話失效了。

對於 tomcat, jetty 這些容器而言,session 就是是一塊在伺服器開闢的記憶體空間,儲存結構就是 map。

tomcat 的 session 實現類是 standardsession。

如果你的應用是單節點部署,這種場景使用web容器實現的 session 機制沒有問題。一但壓力過大,需要多節點部署的時候,session 就需要進行分布式的支援。

看下圖,當部署了兩個 tomcat 的時候,通過 nginx 進行負載均衡,第一次請求**到了 tomcat1, session 資訊儲存在 tomcat1 上面。第二次請求**到了 tomcat2 上面,但是 tomcat2 上面是沒有剛才的 session 資訊,這就是多節點下 session 會出現的問題。

session 複製

tomcat 內建了 session 複製的功能,也就是你的 session 是在 tomcat1 中產生的,tomcat1 會將你的 session 同步給 tomcat2, 這樣當你的請求到了 tomcat2 的時候,就能知道你的身份資訊。

這種方案在其他的框架中也經常能見到,比如 spring cloud 體系中的 eureka 註冊中心,也是採用複製的方式來同步登錄檔的資訊。

關於 tomcat session 複製相關配置請參考官方文件:

黏性會話

黏性會話指的是對於同乙個使用者的請求,永遠都只**到某乙個 tocmat 的例項上,這樣即使沒有做 session 複製,也不會出現問題。如果有節點掛掉了就會訪問失敗。

常見的方式有對 ip 做 hash 進行**,ip 不太可靠,因為會變。在 nginx 中有乙個 nginx-sticky-module 這個第三方模組用於新增乙個粘性 cookie,該粘性 cookie 始終**到同一伺服器。

nginx-sticky-module 會在 cookie 中記錄乙個值來標識當前請求需要被**到哪個節點,第一次沒有的時候會先**,然後在響應給客戶端之前寫入 cookie。後面的請求都會在 cookie 找到對應的標識,然後進行**到固定的節點。

session 集中儲存

session 複製會占用伺服器資源,影響效能。黏性會話存在單點故障風險。更好的分布式 session 方式就是集中式儲存。

所謂集中式儲存就是將會話資訊統一儲存在某個地方,像 tomcat 之類的 web 伺服器本身不儲存會話資訊,這樣後端服務也就是無狀態的,方便隨時擴容。

至於實現方案的話有很多,大家可以自己去實現 httpsession 做對應的儲存讀取邏輯,也可以採用開源的方案。比如 spring session 就是乙個很好的開源方案,上手簡單,支援多種儲存方式,比如 redis, mysql 等。

如果對手寫 spring session 原理感興趣的,也可以參考我之前的這套課程:

token 認證是目前主流的認證方式之一,token 最大的優勢在於無狀態,並且不用儲存會話資訊。也就是說通過 token 就可以知道當前訪問的使用者是誰,不需要去 web 容器的記憶體中獲取,不需要去集中管理會話的儲存中去獲取。

token 的生成方式有多種,可以自己定義固定的格式,比如裡面包含了使用者 id,使用者名稱等資訊。也可以使用目前主流的 jwt 方式。

jwt(json web token)是為了在網路應用環境中傳遞宣告而執行的一種基於 json 的開放標準。jwt 的宣告一般被用在身份提供者和服務提供者間傳遞被認證的使用者身份資訊, 以便從資源伺服器獲取資源。

比如在使用者登入時,基本思路就是使用者提供使用者名稱和密碼給認證伺服器,伺服器驗證使用者提交資訊的合法性;如果驗證成功,會產生並返回乙個 token,後續請求使用者帶上這個 token ,服務端就可以識別這個請求的身份資訊。

jwt 由三部分構成,

乙個 jwt 生成的 token 格式為:

token = encodebase64(header) + '.' + encodebase64(payload) + '.' + encodebase64(signature)

頭部的資訊通常由兩部分內容組成,令牌的型別和使用的簽名演算法,比如下面的**:

訊息體中可以攜帶一些應用需要的資訊,比如使用者 id,**如下:

簽名是用來判斷訊息在傳遞的路徑上是否被篡改的,從而保證資料的安全性,格式如下:

hmacsha256( base64urlencode(header)  + "." +  base64urlencode(payload), secret)

通過這三部分就組成了我們的 json web token。

如何使用請參考 github:

如上圖所示:請求到達 tomcat 後,可以呼叫單獨的 token 服務進行 token 的生成,也可以將 token 的生成邏輯封裝成乙個 jar 包來使用。需要注意的是如果用內嵌的方式,對應 token 的加密配置要一致,否則會出現驗證失敗的情況。

token 有點不好的地方在於無法主動讓它失效,比如我們用 session 的場景,使用者退出登入,直接將 session 資訊在服務端刪除即可,即使後面用相同的 session 資訊去請求,服務端也找不到對應的資訊了。

token 是乙個加密的字串,裡面包含了使用者的資訊,加密演算法,過期時間。如果過期時間設定的比較長,也就意味著在過期時間之前都可以使用。

如果要實現退出登入的功能,既然不能對 token 本身的過期時間進行改造,那麼可以使用乙個黑名單的機制來進行過濾即可。將退出登入的 token 儲存起來,使用的地方去匹配是否登出了,然後進行攔截即可。

剛剛給自己算命了

12年一次的 射手座之年 將是射手座自信出發 出人頭地的幸運年。射手座今年將在熟悉的舞台鶴立雞群,但在進修深造 長途旅行或到國外發展上際遇曲 折。事業在攀高峰的幕後,壓力 矛盾與寂寞加倍。前3季宜把握機會追求夢想 知識 婚姻與愛情,9月中後將進入事業有成和理財致富的豐收季。財運 花得慷慨,賺得也多,...

給學妹改程式

include include using namespace std class complex complex double r,double i complex operator complex c2 complex operator complex c2 complex operator c...

給老婆普及計算機知識

我們知道計算機的計算資料需要從磁碟排程到記憶體,然後再排程到l2 cache,再到l1 cache,最後進cpu暫存器進行計算。給老婆在電腦城買本本的時候向電腦推銷人員問到這些引數,老婆聽不懂,讓我給她解釋,解釋完後,老婆說,原來電腦內部這麼麻煩,怪不得電腦總是那麼慢,直接操作記憶體不就快啦 我是那...