目錄html
Java EE : 3、圖解Session(會話)github
概述web
1、Session由來數據庫
2、Session機制express
3、詳細介紹Seesion機制過程apache
4、補充瀏覽器
5、總結安全
HTTP的無狀態,也就是說,每次請求都是獨立的線程。舉個例子吧:購物中,你選擇了A商品,加入購物車,這就是A線程。而後在選擇B商品就是B線程。但是每次線程獨立(對容器而言,A、B成了不一樣的用戶),線程A不知道有B,B也不知道A。如何一塊兒付款呢?
簡答來講:怎麼保存同個用戶多個請求會話狀態呢?天然HTTPS保證鏈接是安全的,可使它與一個會話關聯。
問題就在於如何跟蹤同一個用戶,選擇天然不少:
一、EJB(有狀態會話bean保存會話狀態) 環境苛刻須要帶EJB的J2EE服務器,而不是Tomcat這種Web容器。
二、數據庫(這貌似萬能的。針對數據)
三、就是咱們要講的HttpSeesion,保存跨一個特定用戶多個請求的會話狀態。
四、上面說的HTTPS,條件太苛刻了。
機制,什麼用詞有點高大上。其實就是把它內在的一點東西說出來。主要兩個W:What?How?
What is Session?
Session表明着服務器和客戶端一次會話的過程。直到session失效(服務端關閉),或者客戶端關閉時結束。
How does session works?
Session 是存儲在服務端的,並針對每一個客戶端(客戶),經過SessionID來區別不一樣用戶的。Session是以Cookie技術或URL重寫實現。默認以Cookie技術實現,服務端會給此次會話創造一個JSESSIONID的Cookie值。
補充:
其實還有一種技術:表單隱藏字段。它也能夠實現session機制。這裏只是做爲補充,服務器響應前,會修改form表單,添加一個sessionID相似的隱藏域,以便傳回服務端的時候能夠標示出此會話。
這技術,也可使用在Web安全上,能夠有效地控制CRSF跨站請求僞造。
圖中這是session第一次請求的詳細圖。以Cookie技術實現,我也寫了個HttpSessionByCookieServletT.java 的Servlet小demo,模擬下Seesion的一輩子。代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
package
org.servlet.sessionMngmt;
import
java.io.IOException;
import
java.io.PrintWriter;
import
javax.servlet.ServletException;
import
javax.servlet.annotation.WebServlet;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
javax.servlet.http.HttpSession;
/*
* Copyright [2015] [Jeff Lee]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Jeff Lee
* @since 2015-7-12 10:58:28
* HttpSession的默認Cookie實現案例
*/
@WebServlet
(urlPatterns =
"/sessionByCookie"
)
public
class
HttpSessionByCookieServletT
extends
HttpServlet {
private
static
final
long
serialVersionUID = 1L;
@Override
protected
void
doGet(HttpServletRequest req, HttpServletResponse resp)
throws
ServletException, IOException {
// 獲取session
// 若是是第一次請求的話,會建立一個HttpSeesion,等同於 req.getSession(true);
// 若是已存在session,則會獲取session。
HttpSession session = req.getSession();
if
(session.isNew()) {
// 設置session屬性值
session.setAttribute(
"name"
,
"Jeff"
);
}
// 獲取SessionId
String sessionId = session.getId();
PrintWriter out = resp.getWriter();
// 若是HttpSeesion是新建的話
if
(session.isNew()) {
out.println(
"Hello,HttpSession! <br>The first response - SeesionId="
+ sessionId +
" <br>"
);
}
else
{
out.println(
"Hello,HttpSession! <br>The second response - SeesionId="
+ sessionId +
" <br>"
);
// 從Session獲取屬性值
out.println(
"The second-response - name: "
+ session.getAttribute(
"name"
));
}
}
}
|
隆重打個小廣告:
泥瓦匠學習的代碼都在github上(同步osc git),歡迎你們點star,提意見,一塊兒進步。地址:https://github.com/JeffLi1993
① 客戶端向服務端發送第一次請求
此時,客戶端想讓服務端把本身的名字設置到會話中。
② 服務端的容器產生該用戶惟一sessionID的session對象,並設置值
能夠從代碼中看出經過從請求中req.getSession(),新生成了一個session對象。並設置了setAttribute(「name」, 「Jeff」),key爲string,value是對象皆可。
這時候,咱們不用再把session經過cookie技術處理,容器幫咱們處理了。
③ 容器響應 Set-Cookie:JSESSIONID= …
咱們能夠F12,查看這次響應。
從圖中可獲得,每一個Cookie的set,都有一個對應Set-Cookie的頭。HttpOnly但是此Cookie只讀模式。只不過session惟一標識是:JSESSIONID
④ 瀏覽器解析Cookie,保存至瀏覽器文件。
如圖,找到了對應的session存儲的cookie文件。該文件被保護不能打開。圖解Cookie 教你怎麼找到該文件。
第二次請求會發什麼變化呢?
下面,泥瓦匠從新訪問了這個地址:
① 再次請求
此時,請求會有Cookie值:JSESSIONID=… 該值傳給服務端
② 容器獲取SessionId
,關聯HttpSession
③ 此時響應無SetCookie
如圖:
可是此次請求,咱們響應出上一次請求set的值。Jeff 就打印出來了!
關於服務端獲取session,也就是從請求中獲取session對象,容器會幫你根據Cookie找到惟一的session對象。
泥瓦匠記憶小抄:Seesion機制,記住兩次請求圖便可。
點到爲止哈~ 之後詳細寫。此圖來自網絡
上圖Bad guy,就是攻擊者。跨站請求僞造,僞造用戶請求來對服務器數據或者是用戶等形成威脅。web安全也就是從這些基礎中慢慢提高。
一、大概地描述了session的工做機制,和一些安全相關。記住Seesion是什麼,怎麼用,在服務端客戶端之間怎麼傳輸便可。