zoukankan      html  css  js  c++  java
  • JavaEE 要懂的小事:三、图解Session(会话)

    Writer      :BYSocket(泥沙砖瓦浆木匠)

    微         博:BYSocket

    豆         瓣:BYSocket

    FaceBook:BYSocket

    Twitter    :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,条件太苛刻了。

    如图: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跨站请求伪造

    三、详细介绍Seesion机制过程

    绘图3

    图中这是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,查看此次响应。

    image

    从图中可得到,每个Cookie的set,都有一个对应Set-Cookie的头。HttpOnly可是此Cookie只读模式。只不过session唯一标识是:JSESSIONID

    ④ 浏览器解析Cookie,保存至浏览器文件。

    image

    如图,找到了对应的session存储的cookie文件。该文件被保护不能打开。图解Cookie 教你怎么找到该文件。

     

    第二次请求会发什么变化呢?

    session2

    下面,泥瓦匠重新访问了这个地址:

    ① 再次请求

    image

    此时,请求会有Cookie值:JSESSIONID=… 该值传给服务端

    ② 容器获取SessionId
    ,关联HttpSession

    ③ 此时响应无SetCookie

    如图:

    image

    但是这次请求,我们响应出上一次请求set的值。Jeff 就打印出来了!

     

    关于服务端获取session,也就是从请求中获取session对象,容器会帮你根据Cookie找到唯一的session对象。

    泥瓦匠记忆小抄:Seesion机制,记住两次请求图即可。

    四、补充

    点到为止哈~ 以后详细写。此图来自网络

    wkiom1l4oh2s5jwhaaa5g2i22fe912

    上图Bad guy,就是攻击者。跨站请求伪造,伪造用户请求来对服务器数据或者是用户等造成威胁。web安全也就是从这些基础中慢慢提升。

     

    五、总结

    1、大概地描述了session的工作机制,和一些安全相关。记住Seesion是什么,怎么用,在服务端客户端之间怎么传输即可。

    2、泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

    Writer      :BYSocket(泥沙砖瓦浆木匠)

    微         博:BYSocket

    豆         瓣:BYSocket

    FaceBook:BYSocket

    Twitter    :BYSocket

  • 相关阅读:
    PAT (Advanced Level) Practice 1055 The World's Richest (25 分) (结构体排序)
    PAT (Advanced Level) Practice 1036 Boys vs Girls (25 分)
    PAT (Advanced Level) Practice 1028 List Sorting (25 分) (自定义排序)
    PAT (Advanced Level) Practice 1035 Password (20 分)
    PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) (进制转换,回文数)
    PAT (Advanced Level) Practice 1120 Friend Numbers (20 分) (set)
    从零开始吧
    Python GUI编程(TKinter)(简易计算器)
    PAT 基础编程题目集 6-7 统计某类完全平方数 (20 分)
    PAT (Advanced Level) Practice 1152 Google Recruitment (20 分)
  • 原文地址:https://www.cnblogs.com/Alandre/p/4640845.html
Copyright © 2011-2022 走看看