JavaEE 要懂的小事:三、圖解Session(會話)

cebp 9年前發布 | 19K 次閱讀 JavaEE Java開發

Writer      :BYSocket(泥沙磚瓦漿木匠)

微         博:BYSocket

豆         瓣:BYSocket

非死book:BYSocket

推ter    :BYSocket

相繼 圖解Http協議  圖解Cookie 之后,中間迷茫期哈,沒寫了!可是又要告訴你自己明明喜歡寫為啥不寫了!那就寫吧,學到老學到老~ 然后寫到老!本系列皆以圖為主,力求簡單易懂,娓娓道來`


一、Session由來

HTTP的無狀態,也就是說,每次請求都是獨立的線程。舉個例子吧:購物中,你選擇了A商品,加入購物車,這就是A線程。然后在選擇B商品就是B線程。可是每次線程獨立(對容器而言,A、B成了不同的用戶),線程A不知道有B,B也不知道A。如何一起付款呢?

簡答來說:怎么保存同個用戶多個請求會話狀態呢?自然HTTPS保證連接是安全的,可以使它與一個會話關聯。

問題就在于如何跟蹤同一個用戶,選擇自然很多:

1、EJB(有狀態會話bean保存會話狀態) 環境苛刻需要帶EJB的J2EE服務器,而不是Tomcat這種Web容器。

2、數據庫(這貌似萬能的。針對數據)

3、就是我們要講的HttpSeesion保存跨一個特定用戶多個請求的會話狀態

4、上面說的HTTPS,條件太苛刻了。

</blockquote>

如圖:JavaEE 要懂的小事:三、圖解Session(會話)

二、Session機制

機制,什么用詞有點高大上。其實就是把它內在的一點東西說出來。主要兩個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跨站請求偽造

</blockquote>

三、詳細介紹Seesion機制過程

JavaEE 要懂的小事:三、圖解Session(會話)

</span>

圖中這是session第一次請求的詳細圖。以Cookie技術實現,我也寫了個HttpSessionByCookieServletT.java 的Servlet小demo,模擬下Seesion的一生。代碼如下:


packageorg.servlet.sessionMngmt;

importjava.io.IOException; importjava.io.PrintWriter;

importjavax.servlet.ServletException; importjavax.servlet.annotation.WebServlet; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjavax.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 *
  • http://www.apache.org/licenses/LICENSE-2.0 *
  • 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") publicclassHttpSessionByCookieServletT extendsHttpServlet {

    privatestaticfinallongserialVersionUID = 1L;

    @Override protectedvoiddoGet(HttpServletRequest req, HttpServletResponse resp)

        throwsServletException, 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"));
    }
    
    

    }

}</pre>




隆重打個小廣告:

泥瓦匠學習的代碼都在github上(同步osc git),歡迎大家點star,提意見,一起進步。地址:https://github.com/JeffLi1993

</blockquote>

① 客戶端向服務端發送第一次請求

此時,客戶端想讓服務端把自己的名字設置到會話中。

② 服務端的容器產生該用戶唯一sessionID的session對象,并設置值

可以從代碼中看出通過從請求中req.getSession(),新生成了一個session對象。并設置了setAttribute(“name”, “Jeff”),key為string,value是對象皆可。

這時候,我們不用再把session通過cookie技術處理,容器幫我們處理了。

③ 容器響應 Set-Cookie:JSESSIONID= …

我們可以F12,查看此次響應。

JavaEE 要懂的小事:三、圖解Session(會話)

</span>

從圖中可得到,每個Cookie的set,都有一個對應Set-Cookie的頭。HttpOnly可是此Cookie只讀模式。只不過session唯一標識是:JSESSIONID

 瀏覽器解析Cookie,保存至瀏覽器文件。

JavaEE 要懂的小事:三、圖解Session(會話)

如圖,找到了對應的session存儲的cookie文件。該文件被保護不能打開。圖解Cookie 教你怎么找到該文件。


第二次請求會發什么變化呢?

JavaEE 要懂的小事:三、圖解Session(會話)

下面,泥瓦匠重新訪問了這個地址:

① 再次請求

JavaEE 要懂的小事:三、圖解Session(會話)

此時,請求會有Cookie值:JSESSIONID=… 該值傳給服務端

② 容器獲取SessionId
,關聯HttpSession

③ 此時響應無SetCookie

如圖:

JavaEE 要懂的小事:三、圖解Session(會話)

但是這次請求,我們響應出上一次請求set的值。Jeff 就打印出來了!


關于服務端獲取session,也就是從請求中獲取session對象,容器會幫你根據Cookie找到唯一的session對象。

泥瓦匠記憶小抄:Seesion機制,記住兩次請求圖即可。

</span>

四、補充

點到為止哈~ 以后詳細寫。此圖來自網絡

JavaEE 要懂的小事:三、圖解Session(會話)

上圖Bad guy,就是攻擊者。跨站請求偽造,偽造用戶請求來對服務器數據或者是用戶等造成威脅。web安全也就是從這些基礎中慢慢提升。


五、總結

1、大概地描述了session的工作機制,和一些安全相關。記住Seesion是什么,怎么用,在服務端客戶端之間怎么傳輸即可。

2、泥瓦匠學習的代碼都在github上(同步osc git),歡迎大家點star,提意見,一起進步。地址:https://github.com/JeffLi1993

</blockquote>

Writer      :BYSocket(泥沙磚瓦漿木匠)

微         博:BYSocket

豆         瓣:BYSocket

非死book:BYSocket

推ter    :BYSocket

 本文由用戶 cebp 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!