① java web的怎麼通過sessionid得到session
在回答問題之前,跟你簡單介紹Session的工作原理:
不需要寫手動寫SessionID:
代碼如下:
HttpSessionsesion=Request.getSesion();
if(session!=null){
//如果sessionID不等於空版,則說明是權第二次訪問
//寫第二次訪問時的代碼
}else{
//寫第一次訪問的代碼
}
javaweb怎麼通過sessionid得到session這個我們不需要了解,就是第二次客戶端發出請求時,將sessionid也發給了伺服器,伺服器根據這個唯一的ID找到相應的session(session都是保存在伺服器的資料庫中,每個session用唯一一個ID所標識),就像是資料庫中根據關鍵字查找數據一樣,找到之後就可以直接用這個session裡面的數據了。
② java session怎麼來的
HTTP協議 ( http://www.w3.org/Protocols/ )是「一次性單向」協議。
服務端不能主動連接客戶端,只能被動等待並答復客戶端請求。客戶端連接服務端,發出一個HTTP Request,服務端處理請求,並且返回一個HTTP Response給客戶端,本次HTTP Request-Response Cycle結束。
我們看到,HTTP協議本身並不能支持服務端保存客戶端的狀態信息。於是,Web Server中引入了session的概念,用來保存客戶端的狀態信息。
這里用一個形象的比喻來解釋session的工作方式。假設Web Server是一個商場的存包處,HTTP Request是一個顧客,第一次來到存包處,管理員把顧客的物品存放在某一個櫃子裡面(這個櫃子就相當於Session),然後把一個號碼牌交給這個顧客,作為取包憑證(這個號碼牌就是Session ID)。顧客(HTTP Request)下一次來的時候,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據號碼牌(Session ID)找到相應的櫃子(Session),根據顧客(HTTP Request)的請求,Web Server可以取出、更換、添加櫃子(Session)中的物品,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應的櫃子(Session)失效。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)。這樣,顧客(HTTP Request)下次來的時候,就又帶著號碼牌回來了。
我們可以看到,Session ID實際上是在客戶端和服務端之間通過HTTP Request和HTTP Response傳來傳去的。
我們看到,號碼牌(Session ID)必須包含在HTTP Request裡面。關於HTTP Request的具體格式,請參見HTTP協議(http://www.w3.org/Protocols/ )。這里只做一個簡單的介紹。
在Java Web Server(即Servlet/jsP Server)中,Session ID用jsessionid表示(請參見Servlet規范)。
HTTP Request一般由3部分組成:
(1)Request Line
這一行由HTTP Method(如GET或POST)、URL、和HTTP版本號組成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
GET http://www.google.com/search?q=Tomcat HTTP/1.1
POST http://www.google.com/search HTTP/1.1
GET http://www.somsite.com/menu.do;jsessionid=1001 HTTP/1.1
(2)Request Headers
這部分定義了一些重要的頭部信息,如,瀏覽器的種類,語言,類型。Request Headers中還可以包括Cookie的定義。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Language: en-us
Cookie: jsessionid=1001
(3)Message Body
如果HTTP Method是GET,那麼Message Body為空。
如果HTTP Method是POST,說明這個HTTP Request是submit一個HTML Form的結果,
那麼Message Body為HTML Form裡面定義的Input屬性。例如,
user=guest
password=guest
jsessionid=1001
主意,如果把HTML Form元素的Method屬性改為GET。那麼,Message Body為空,所有的Input屬性都會加在URL的後面。你在瀏覽器的URL地址欄中會看到這些屬性,類似於
http://www.somesite/login.do?user=guest&password=guest&jsessionid=1001
從理論上來說,這3個部分(Request URL,Cookie Header, Message Body)都可以用來存放Session ID。由於Message Body方法必須需要一個包含Session ID的HTML Form,所以這種方法不通用。
一般用來實現Session的方法有兩種:
(1)URL重寫。
Web Server在返回Response的時候,檢查頁面中所有的URL,包括所有的連接,和HTML Form的Action屬性,在這些URL後面加上「;jsessionid=XXX」。
下一次,用戶訪問這個頁面中的URL。jsessionid就會傳回到Web Server。
(2)Cookie。
如果客戶端支持Cookie,Web Server在返回Response的時候,在Response的Header部分,加入一個「set-cookie: jsessionid=XXXX」header屬性,把jsessionid放在Cookie里傳到客戶端。
客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時候,再把Cookie的信息放到HTTP Request的「Cookie」header屬性裡面,這樣jsessionid就隨著HTTP Request返回給Web Server。
我們來看Tomcat5的源代碼如何支持jsessionid。
org.apache.coyote.tomcat5.CoyoteResponse類的toEncoded()方法支持URL重寫。
String toEncoded(String url, String sessionId) {
…
StringBuffer sb = new StringBuffer(path);
if( sb.length() > 0 ) { // jsessionid can't be first.
sb.append(";jsessionid=");
sb.append(sessionId);
}
sb.append(anchor);
sb.append(query);
return (sb.toString());
}
我們來看org.apache.coyote.tomcat5.CoyoteRequest的兩個方法configureSessionCookie()
doGetSession()用Cookie支持jsessionid.
/**
* Configures the given JSESSIONID cookie.
*
* @param cookie The JSESSIONID cookie to be configured
*/
protected void configureSessionCookie(Cookie cookie) {
…
}
HttpSession doGetSession(boolean create){
…
// Creating a new session cookie based on that session
if ((session != null) && (getContext() != null)
&& getContext().getCookies()) {
Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
session.getId());
configureSessionCookie(cookie);
((HttpServletResponse) response).addCookie(cookie);
}
…
}
Session的典型應用是存放用戶的Login信息,如用戶名,密碼,許可權角色等信息,應用程序(如Email服務、網上銀行等系統)根據這些信息進行身份驗證和許可權驗證
③ java如何獲取sessionid
這個功能老版本servlet規范中有,新版本中好像被屏蔽了。可以換一種做法,寫一個session監聽。創建時將session
id與session對象構造一個hashMap放到
application中去,銷毀時從application中移除。然後你就可以獲取了。
④ javaweb為什麼瀏覽器的地址欄會出現sessionid
是為了讓web伺服器能記住你!
第一次訪問:請求中不會有sessionid,響應中會有sessionid,這是伺服器發給你的身份標識;
第二次訪問:你的瀏覽器會自動把這個sessionid發給伺服器,伺服器就能認出你是上次訪問過的那個用戶;
第三次和以後都是這樣;
當瀏覽器關閉後,這個sessionId就會失效;
sessionid就是在瀏覽器一次開閉過程中,讓伺服器能記住你的一種機制;
因為不同的http請求之間是沒有關聯的,伺服器為了分辨哪些請求來自同一台電腦,就有了session機制,
⑤ java web應用如何實現單點登錄
實現方式一:父域 Cookie
實現方式二:認證中心
實現方式三:LocalStorage跨域
補充:域名分級
在 B/S 系統中,登錄功能通常都是基於 Cookie 來實現的。當用戶登錄成功後,一般會將登錄狀態記錄到 Session 中,或者是給用戶簽發一個 Token,無論哪一種方式,都需要在客戶端保存一些信息(Session ID 或 Token ),並要求客戶端在之後的每次請求中攜帶它們。在這樣的場景下,使用 Cookie 無疑是最方便的,因此我們一般都會將 Session 的 ID 或 Token 保存到 Cookie 中,當服務端收到請求後,通過驗證 Cookie 中的信息來判斷用戶是否登錄 。
單點登錄(Single Sign On, SSO)是指在同一帳號平台下的多個應用系統中,用戶只需登錄一次,即可訪問所有相互信任的應用系統。舉例來說,網路貼吧和網路地圖是網路公司旗下的兩個不同的應用系統,如果用戶在網路貼吧登錄過之後,當他訪問網路地圖時無需再次登錄,那麼就說明網路貼吧和網路地圖之間實現了單點登錄。
單點登錄的本質就是在多個應用系統中共享登錄狀態。如果用戶的登錄狀態是記錄在 Session 中的,要實現共享登錄狀態,就要先共享 Session,比如可以將 Session 序列化到 Redis 中,讓多個應用系統共享同一個 Redis,直接讀取 Redis 來獲取 Session。
當然僅此是不夠的,因為不同的應用系統有著不同的域名,盡管 Session 共享了,但是由於 Session ID 是往往保存在瀏覽器 Cookie 中的,因此存在作用域的限制,無法跨域名傳遞,也就是說當用戶在 app1.com 中登錄後,Session ID 僅在瀏覽器訪問 app1.com 時才會自動在請求頭中攜帶,而當瀏覽器訪問 app2.com 時,Session ID 是不會被帶過去的。實現單點登錄的關鍵在於,如何讓 Session ID(或 Token)在多個域中共享。
實現方式一:父域 Cookie
在將具體實現之前,我們先來聊一聊 Cookie 的作用域。
Cookie 的作用域由 domain 屬性和 path 屬性共同決定。domain 屬性的有效值為當前域或其父域的域名/IP地址,在 Tomcat 中,domain 屬性默認為當前域的域名/IP地址。path 屬性的有效值是以「/」開頭的路徑,在 Tomcat 中,path 屬性默認為當前 Web 應用的上下文路徑。
如果將 Cookie 的 domain 屬性設置為當前域的父域,那麼就認為它是父域 Cookie。Cookie 有一個特點,即父域中的 Cookie 被子域所共享,換言之,子域會自動繼承父域中的Cookie。
利用 Cookie 的這個特點,不難想到,將 Session ID(或 Token)保存到父域中不就行了。沒錯,我們只需要將 Cookie 的 domain 屬性設置為父域的域名(主域名),同時將 Cookie 的 path 屬性設置為根路徑,這樣所有的子域應用就都可以訪問到這個 Cookie 了。不過這要求應用系統的域名需建立在一個共同的主域名之下,如 tieba..com 和 map..com,它們都建立在 .com 這個主域名之下,那麼它們就可以通過這種方式來實現單點登錄。
總結:此種實現方式比較簡單,但不支持跨主域名。
實現方式二:認證中心
我們可以部署一個認證中心,認證中心就是一個專門負責處理登錄請求的獨立的 Web 服務。
用戶統一在認證中心進行登錄,登錄成功後,認證中心記錄用戶的登錄狀態,並將 Token 寫入 Cookie。(注意這個 Cookie 是認證中心的,應用系統是訪問不到的。)
應用系統檢查當前請求有沒有 Token,如果沒有,說明用戶在當前系統中尚未登錄,那麼就將頁面跳轉至認證中心。由於這個操作會將認證中心的 Cookie 自動帶過去,因此,認證中心能夠根據 Cookie 知道用戶是否已經登錄過了。如果認證中心發現用戶尚未登錄,則返回登錄頁面,等待用戶登錄,如果發現用戶已經登錄過了,就不會讓用戶再次登錄了,而是會跳轉回目標 URL ,並在跳轉前生成一個 Token,拼接在目標 URL 的後面,回傳給目標應用系統。
應用系統拿到 Token 之後,還需要向認證中心確認下 Token 的合法性,防止用戶偽造。確認無誤後,應用系統記錄用戶的登錄狀態,並將 Token 寫入 Cookie,然後給本次訪問放行。(注意這個 Cookie 是當前應用系統的,其他應用系統是訪問不到的。)當用戶再次訪問當前應用系統時,就會自動帶上這個 Token,應用系統驗證 Token 發現用戶已登錄,於是就不會有認證中心什麼事了。
這里順便介紹兩款認證中心的開源實現:
Apereo CAS 是一個企業級單點登錄系統,其中 CAS 的意思是」Central Authentication Service「。它最初是耶魯大學實驗室的項目,後來轉讓給了 JASIG 組織,項目更名為 JASIG CAS,後來該組織並入了Apereo 基金會,項目也隨之更名為 Apereo CAS。
XXL-SSO 是一個簡易的單點登錄系統,由大眾點評工程師許雪裡個人開發,代碼比較簡單,沒有做安全控制,因而不推薦直接應用在項目中,這里列出來僅供參考。
總結:此種實現方式相對復雜,支持跨域,擴展性好,是單點登錄的標准做法。
實現方式三:LocalStorage 跨域
前面,我們說實現單點登錄的關鍵在於,如何讓 Session ID(或 Token)在多個域中共享。
父域 Cookie 確實是一種不錯的解決方案,但是不支持跨域。那麼有沒有什麼奇淫技巧能夠讓 Cookie 跨域傳遞呢?
很遺憾,瀏覽器對 Cookie 的跨域限制越來越嚴格。Chrome 瀏覽器還給 Cookie 新增了一個 SameSite 屬性,此舉幾乎禁止了一切跨域請求的 Cookie 傳遞(超鏈接除外),並且只有當使用 HTTPs 協議時,才有可能被允許在 AJAX 跨域請求中接受伺服器傳來的 Cookie。
不過,在前後端分離的情況下,完全可以不使用 Cookie,我們可以選擇將 Session ID (或 Token )保存到瀏覽器的 LocalStorage 中,讓前端在每次向後端發送請求時,主動將 LocalStorage 的數據傳遞給服務端。這些都是由前端來控制的,後端需要做的僅僅是在用戶登錄成功後,將 Session ID (或 Token )放在響應體中傳遞給前端。
在這樣的場景下,單點登錄完全可以在前端實現。前端拿到 Session ID (或 Token )後,除了將它寫入自己的 LocalStorage 中之外,還可以通過特殊手段將它寫入多個其他域下的 LocalStorage 中。
————————————————
版權聲明:本文為CSDN博主「風水道人」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/jcmj123456/article/details/114296482
前端通過 iframe+postMessage() 方式,將同一份 Token 寫入到了多個域下的 LocalStorage 中,前端每次在向後端發送請求之前,都會主動從 LocalStorage 中讀取 Token 並在請求中攜帶,這樣就實現了同一份 Token 被多個域所共享。
總結:此種實現方式完全由前端控制,幾乎不需要後端參與,同樣支持跨域。
補充:域名分級
從專業的角度來說(根據《計算機網路》中的定義),.com、.cn 為一級域名(也稱頂級域名),.com.cn、.com 為二級域名,sina.com.cn、tieba..com 為三級域名,以此類推,N 級域名就是 N-1 級域名的直接子域名。
從使用者的角度來說,一般把可支持獨立備案的主域名稱作一級域名,如 .com、sina.com.cn 皆可稱作一級域名,在主域名下建立的直接子域名稱作二級域名,如 tieba..com 為二級域名。
⑥ Java中session是怎樣定義的,它的作用域在哪
首先要明確一個概念,session並不是java獨有的,而是基於http的(jsp、asp.net、php等等技術都會涉及到session),下面我來講解一下sessin的具體內容:
session機制是一種伺服器端的機制,伺服器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
當程式需要為某個客戶端的請求創建一個session的時候,伺服器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為session id,如果已包含一個session id則說明以前已為此客戶端創建過session,伺服器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session並且生成一個和此session相關聯的session id,session id的值應該是個既不會重復,植蝗菀妝徽業焦媛梢苑略斕淖址???飧?ession id將被在本次響應中返回給客戶端保存。
保存這個session id的方式能採用cookie,這樣在交互過程中瀏覽器能自動的按照規則把這個標識發揮給伺服器。一般這個cookie的名字都是類似於SEEESIONID,而。比如weblogic對於web應用程式生成的cookie,JSESSIONID=!-145788764,他的名字就是JSESSIONID。
由於cookie能被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回伺服器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764另一種是作為查詢字元串附加在URL後面,表現形式為http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764
這兩種方式對於用戶來說是沒有差別的,只是伺服器在解析的時候處理的方式不同,採用第一種方式也有利於把session id的信息和正常程式參數區分開來。
為了在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。
另一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,添加一個隱藏欄位,以便在表單提交時能夠把session id傳遞回伺服器。
這種技術目前已較少應用,筆者接觸過的非常古老的iPlanet6(SunONE應用伺服器的前身)就使用了這種技術。實際上這種技術能簡單的用對action應用URL重寫來代替。
在談論session機制的時候,常常聽到這樣一種誤解「只要關閉瀏覽器,session就消失了」。其實能想像一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是相同的,除非程式通知伺服器刪除一個session,否則伺服器會一直保留,程式一般都是在用戶做log off的時候發個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知伺服器他將要關閉,因此伺服器根本不會有機會知道瀏覽器已關閉,之所以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個session id就消失了,再次連接伺服器時也就無法找到原來的session。如果伺服器設置的cookie被保存到硬碟上,或使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給伺服器,則再次打開瀏覽器仍然能夠找到原來的session。
恰恰是由於關閉瀏覽器不會導致session被刪除,迫使伺服器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,伺服器就能認為客戶端已停止了活動,才會把session刪除以節省存儲空間。