***********************************
session 工作原理是什麼?
***********************************
因為 http 協議是無狀態的, 對於伺服器端來講, 如何為不同的訪問使用者提供不一樣的體驗呢? 比如郵箱系統, 只有登入使用者才能收發郵件.
這就需要伺服器能識別每乙個客戶端訪問, 知道哪些訪問是來自乙個同乙個客戶端, 顯然這個事情光靠伺服器端是做不到的, 需要瀏覽器配合才行, 瀏覽器端 cookie 概念就這麼產生了.
session 工作原理:
(1) 當乙個 session 第一次被啟動時, 伺服器端先產生乙個唯一的 session id, 並為該 session id 分配乙個記憶體區, 用來儲存該 session 相關的資訊. 然後將該 id 儲存到瀏覽器的 cookie 中, cookie name 為 jsessionid.
(2) 瀏覽器每次訪問, 都會帶上本域下所有的 cookie, 包括這個 jsessionid cookie(應該是放到 http header 上的), 伺服器端通過對比 jsessionid 和伺服器記憶體中的 session id, 就能識別哪些訪問是來自同乙個客戶端.
(3) 伺服器端在每次訪問中, 都可以在 jsessionid 對應的 session 記憶體區中記錄一些資訊, 比如最後一次的訪問時間, 比如訪問 ip 值, 以滿足業務需求.
***********************************
session 的用途有哪些?
***********************************
1. 核心功能: 是識別每乙個訪問.
2. 基本功能: 做登入驗證, 然後就能得到登入 id, 進而能完成許可權驗證.
核心功能和基本功能都由 spring web 框架提供, 或 shiro 這樣安全框架提供, 我們的**不用直接處理這些事情.
3. 利用 session, 可以衍生出更多的功能, 比如儲存訪客上次訪問的 ip 和上次訪問時間, 比如儲存 user id 和 user name, 這裡稍微要多想一下:
(1). 這些資料既可以儲存到 db 中, 也可以儲存到 session 記憶體中, user id 和 user name 在 db 中本來就儲存著, 有必要在 session 中儲存嗎?
session 的優點是訪問速度快, 缺點是使用者量大的情況下記憶體占用是個問題.
(2). 這些資料既可以儲存到 cookie , 也可以儲存到 session 記憶體中, 哪個更適合?
cookie 的優點是: 不占用伺服器端記憶體, session 佔伺服器記憶體並且重啟後就沒了, cookie 可以被js訪問到, 常用的網頁埋點就是把一些標記資訊儲存到cookie, 然後由js提交到埋點伺服器中.
cookie 的缺點是, cookie 資料如果較大, 會消耗較多的網路頻寬; 使用者隨意修改 cookie 值, 這樣的話, cookie的資料就不太可靠了; 另外, 使用者換個瀏覽器或者瀏覽器清個快取, 原有的cookie就沒法用了.
這些問題都沒有標準答案, 按照具體情形做選擇吧.
***********************************
jsessionid cookie 是到底是在什麼時候生成?
***********************************
jsessionid cookie 並不是在第一次訪問**時候立即生成的, 只有訪問 url 對應檢視函式中有 session 相應操作時, 瀏覽器端才會建立 jsessionid cookie 的.
當然, 一般**在首頁訪問的檢視函式基本都會有 session 操作, 所以給我們的錯覺是, 一旦新訪問乙個**, jsessionid cookie 就自動產生了.
比如訪問 http://localhost:8080/ 主頁, 訪問第乙個測試**的首頁, 並不會建立 jsessionid cookie.
//該 url 請求沒有任何與 session 相關的操作, 瀏覽器端不會建立該**的 jsessionid cookie
//在 url 請求中, 有獲取 session 物件的指令, 瀏覽器端會建立該**的 jsessionid cookie
//在 url 請求中, 檢視函式要注入 session 物件, 瀏覽器端會建立該**的 jsessionid cookie
jsessionid 的 id 值會登入後會變化嗎?
***********************************
假設在登入之前, 瀏覽器端已經有了 jsessionid cookie. 現在問題來了, 在使用者登入之後, 該 jsessionid id 值是否變化?
答案是: 早期**, 登入前後 jsessionid 是不變的, 但後來發現, 如果登入前後 jsessionid 不變, 會有中間人攻擊風險. 所以現在的安全框架在登入完成後, 會自動修改 jsessionid 值. 我們開發**不需要再專門修改 jsessionid.
和登入不一樣, 登入退出 jsessionid 的 id 值並不會改變.
***********************************
session 和 cookie 之間的關係?
***********************************
前面已經提到為了標識同乙個客戶端訪問, 光靠伺服器端的 session 是不夠的, 還需要客戶端 jsessionid cookie 支援. 這體現了 session 和 cookie 之間最重要的乙個關係.
另外, 在 web 開發中 session 和 cookie 有一些很類似的方法, 往往會引起混淆, 有必要區別一下.
1. session:
2. cookie:
***********************************
spring 中 session 和 cookie 的操作方式
***********************************
spring session操作很簡單:
1. 在檢視函式中使用 @cookievalue 修飾形參, 可注入乙個 cookie 屬性值.
@responsebody
public string read(@cookievalue(value = "foo", defaultvalue = "hello") string foocookie)
2. 使用 httpservletresponse.addcookie() 完成 cookie 的寫入.
ajax 呼叫過程中是否會附加cookie資訊?
******************************====
如果 web 應用通過 jquery ajax 呼叫後台 api url, 呼叫過程是否會附加cookie資訊, 要看情況:
1. 如果是同域, ajax 請求會自動帶上本域的cookie, 這台web伺服器本身也有相應的 session 資訊, 所以ajax請求自然能通過 session-cookie 完成身份驗證, 整個過程非常自然.
2. 如果 ajax呼叫的api 是另乙個域下的url, 因為不是同域, 需要手動在ajax呼叫時加上cookie, 可參考: 伺服器端返回response也需要做相應的處理, 另外也需要引入分布式session儲存.
2. 對於微服務專案, 一般和 oauth2/session 無關, 多數基於 jwt 的無狀態認證機制, 通過 jwt 來識別訪問者, 不過還是推薦將jwt前移到api 閘道器較好, 微服務僅僅關注業務邏輯.
完整微服務認證過程是: sso登陸驗證通過後, sso**到統一auth服務來生成乙個jwt token, 並傳給客戶端, 客戶端可將 jwt token儲存到本地(web 客戶端可儲存到 cookie 中), 每次客戶端請求需要將 jwt token 加到 http authorization header上, 伺服器端僅需要 jwt 演算法就可以完成驗證(通常不會再查詢資料庫驗證), 並能提取 username 資訊.
詳細過程和原始碼, 可參考下面幾個文章:
張開濤部落格<
詳細shiro jwt 構建無狀態分布式鑑權體系
shiro+jwt+spring boot restful簡易教程
ECshop中的session機制理解
在網上找了發現都是來之一人之手,也沒有用自己的話去解釋,這裡我就拋磚引玉,發表一下自己的意見,還希望能得到各界人士的指導批評!此session機制不需要session start初始化,這個我一直不太清楚還得專家詳解。自認為此種機制是建立在cookie基礎上的模擬session,先用 globals...
Web專案開發中SESSION(會話)的使用
session會話物件在web應用系統中非常重要,session資源也非常寶貴,session會占用應用伺服器記憶體,門戶 的併發使用者在不斷增長,session物件也不斷增長。所以為了保證 效能,開發人員在開發應用程式時,應該遵循以下幾點 盡量保證session只儲存應用程式狀態資料,而不要儲存各...
關於session的理解
session用於儲存有關使用者 客戶端 瀏覽器 會話的資訊。session 變數儲存的資訊是單一使用者的,並且可 用程式中的所有頁面使用。使用者開啟瀏覽器訪問 瀏覽器的cookie中會生成sessionid,在每次請求時都會自動帶上sessionid,然後伺服器端根據sessionid找到對應的s...