最近在工作中碰到了session與cookie的問題,現在對碰到的問題進行回顧。
1.cookie機制是用戶端保持會話的機制,将客戶的會話資訊儲存在用戶端。session機制是服務端保持會話的機制,是将客戶的會話資訊儲存在服務端。
2.在采用cookie機制的時候,不需要服務端來配合,cookie可以獨立的完成使用者的會話跟蹤
3.在采用session機制的時候,由于服務端存放session以後,必須将sessionId回傳給用戶端,用戶端在後面請求必須攜帶sessionId,服務端端才可以判斷使用者。session保持會話時,用戶端必須有一種方式存放sessionId,常用的就是寫入用戶端的cookie,這種情況下session就需要用戶端cookie累配合保持會話,當然其他的也可以采用URL重寫的方式每次發送請求的時候将sessionID攜帶URL或者表單中,通過URL而非cookie來實作會話跟蹤。
4.tomcat的session的實作機制是采用服務端session+用戶端cookie存放sessionId的方式來實作會話跟蹤。如果浏覽器禁用cookie,則這種方式的session會失效。
正常的session驗證的流程應該是如下時序圖:
浏覽器一共發起兩次請求,在第一次發起請求服務端驗證通過後回寫浏覽器的cookie,寫入sessionId,浏覽器第二次通路的時候會自動攜帶cookie資訊,伺服器根據cookie資訊完成隐式驗證。
現在遇到一種這樣的場景:
第三方網站的使用者通過第三方的注冊頁面進行注冊,第三方背景注冊接口在處理注冊請求同時,向認證伺服器發送注冊請求,完成在我方的注冊操作,同時使用者希望注冊完成後就直接跳轉到我方登入态的頁面,不需要使用者再手動登入一次。這種場景一般出現在跨域的登入和頁面通路。
這樣的場景中存在與正常的登入流程的一個差別是,浏覽器在發起第一次的注冊請求的時候,并不是直接請求的認證伺服器,認證伺服器在注冊後,即使生成了tomcat session,但是并不能将sessionId寫入浏覽器的cookie中,原因在于浏覽器并不是直接與認證伺服器互動,中間是經過了一個第三方的伺服器轉發請求。
問題的産生:由于浏覽器不直接與認證伺服器互動,認證伺服器産生session後,無法将sessionId寫入浏覽器的cookie中
一種解決的方案是:
在浏覽器第一次發起注冊請求,認證伺服器完成注冊,登入處理後,生成一個登入憑證,傳回給浏覽器,然後浏覽攜帶登入憑證直接調用認證伺服器進行使用者身份驗證(顯式驗證),驗證通過後再生成tomcat session,回寫sessionId到浏覽器cookie中,然後浏覽器再通過cookie發起需cookie方式認證的頁面。
其與正常的session認證的流程是在注冊登入請求與頁面請求之間,加入了一個顯式的sessionId驗證使用者身份的請求,通過一次顯式的驗證請求來回寫cookie切換到隐式的身份驗證。
其時序圖如下:
其解決的思路是通過一次顯式的驗證(session+url攜帶sessionId)來過渡切換到隐式的登入(session+浏覽器cookie攜帶sessionId)。