您当前的位置: 首页 > 

梁云亮

暂无认证

  • 1浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Session

梁云亮 发布时间:2019-11-04 14:59:50 ,浏览量:1

Session 介绍

session 是存放在服务器的内存中的一份数据。

服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

说明:

  • 服务器通过Cookie发送给客户端一个sessionID
  • sessionID对应服务器里的一小块内存,这里保存着用户的信息,例如登录信息,购物车信息等。
  • 每次用户访问服务器的时候,服务器通过浏览器发送来的cookie里的sessionID去读取对应的内存里的信息,以此来知道用户的隐私信息。

注意:

  • session的好处是防止用户随意篡改cookie,获取别人的信息。

  • 如果用户随意篡改了sessionID,那么只能重新登录。

  • 因为sessionID是随机数,或者随机数夹杂着一些字母,所以没有可能暴力破解sessionID,获取别的用户的信息。

  • 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session。

  • 典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几件物品。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件、集群等。

  • 服务端如何识别特定的客户?第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,就可以依据此来识别不同客户端了。

  • 如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。

Session 信息都是放在内存中的,用户第一次请求创建Session的时候,服务端会在客户端 Cookie 里面记录这个Session ID,以JSESSIONID的方式来保存,以后每次请求都会把这个会话Session ID发送到服务器,根据Session ID服务器就可以知道是谁在访问了。

Session相对是安全的:Session ID可以被劫持与伪造,所以Session ID不能是固定的。 防止Session ID被劫持的方法:

  • 每次在接受Session ID后进行销毁,然后将其中的数据保存在新的Session中。这种方式也不是很可靠,只是相对可靠,可以利用间隙时间劫持
  • 设置httpOnly属性。httpOnly是cookie的扩展属性,并不包含在servlet2.x的规范里,因此,一些JavaEE应用服务器并不支持httpOnly,针对tomcat >6.0.19或者>5.5.28的版本才支持httpOnly属性,使用方法:
 ... 

response.setHeader( "Set-Cookie", "name=value; HttpOnly");

倘若Cookie被禁用,那么需要url重写来解决该问题(在路径后面自动拼接sessionId)。 url重写:

String path = resp.encodeURL("path")(转发);
String path = response.encodeRedirectURL("path")(重定向);
session与cookie的关系

一般来说,Session 基于 Cookie 来实现。

  • Cookie
  1. 服务器通过 Set-Cookie 头给客户端一串字符串
  2. 客户端每次访问相同域名的网页时,必须带上这段字符串
  3. 客户端要在一段时间内保存这个Cookie
  4. Cookie 默认在用户关闭页面后就失效,后台代码可以任意设置 Cookie 的过期时间
  5. 大小大概在 4kb 以内
  • Session
  1. 将 SessionID(随机数)通过 Cookie 发给客户端
  2. 客户端访问服务器时,服务器读取 SessionID
  3. 服务器有一块内存(哈希表)保存了所有 session
  4. 通过 SessionID 我们可以得到对应用户的隐私信息,如 id、email
  5. 这块内存(哈希表)就是服务器上的所有 session
cookie和session的区别
  • session是存储服务器端,cookie是存储在客户端,所以session的安全性比cookie高。
  • 获取session里的信息是通过存放在会话cookie里的session id获取的。而session是存放在服务器的内存中里,所以session里的数据不断增加会造成服务器的负担,所以会把很重要的信息存储在session中,而把一些次要东西存储在客户端的cookie里。
  • cookie确切的说分为两大类:会话cookie和持久化cookie。
    • 会话cookie是存放在客户端浏览器的内存中,他的生命周期和浏览器是一致的,当浏览器关闭会话cookie也就消失了
    • 持久化cookie是存放在客户端硬盘中,持久化cookie的生命周期是我们在设置cookie时候设置的那个保存时间,session的信息是通过sessionid获取的,而sessionid是存放在会话cookie当中的,当浏览器关闭的时候会话cookie消失,所以sessionid也就消失了,但是session的信息还存在服务器端,只是查不到所谓的session但它并不是不存在。所以session在服务器关闭的时候,或者是sessio过期,又或者调用了invalidate(),再或者是session中的某一条数据消失调用session.removeAttribute()方法,session在通过调用session.getsession来创建的。

Session和Cookie的目的相同,都是为了克服HTTP协议无状态的缺陷,但完成的方法不同。Session通过Cookie,在客户端保存SessionID,而将用户的其他会话消息保存在服务端的Session对象中,与此相对的,Cookie需要将所有信息都保存在客户端。因此Cookie存在着一定的安全隐患,例如本地Cookie中保存的用户名密码被破译,或Cookie被其他网站收集。

示例:

用户登录,将用户的信息保存到Session中,用户访问index.jsp资源时需要登录权限:先从Session中取用户信息,取到认为用户已经登录,打开该页面;没有取到则认为用户没有登录,打开登录页面.

  • login.jsp

    
    
    
        login
    
    
        
            用户名:
            密码:
            
        
    
    
    
  • LoginServlet.java

    @WebServlet(urlPatterns = "/loginServlet")
    public class LoginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String uname = request.getParameter("uname");
            String upwd = request.getParameter("upwd");
    
            if ("zhangsan".equals(uname) && "1234".equals(upwd)) {//如果登录成功
                HttpSession session = request.getSession(); //获取Session
                session.setMaxInactiveInterval(60); //设置session的有效时间为60s
                session.setAttribute("user",uname);//将用户信息放到Session中
    
                request.getRequestDispatcher("/index.jsp").forward(request, response);
            }
        }
    }
    
  • DemoServlet.java

    @WebServlet(urlPatterns = "/demoServlet")
    public class DemoServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
            Object user = session.getAttribute("user");
            if(user != null){//如果Session中有user信息,就认为用户已经登录
                request.getRequestDispatcher("/index.jsp").forward(request,response);
            }else {
                response.sendRedirect("/login.jsp");
            }
        }
    }
    
  • 运行

  1. 先请求demoServlet,请求访问index.jsp,发现直接打开了login.jsp页面
  2. 在login.jsp页面中输入用户名称密码,登录,在DemoServlet中,会将用户信息保存在Session中,最后打开index.jsp页面
  3. 再请求demoServlet,在DemoServlet中,发现Session中有User信息了,所以能访问到了index.jsp
关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0408s