zoukankan      html  css  js  c++  java
  • 彻底搞懂Session与Cookie的异同!

    什么是Cookie?

    • Cookie服务器通知客户端保存键值对的一种技术
    • 客户端有了Cookie之后,每次请求都会将Cookie发送给服务器
    • 每个Cookie的大小不能超过4kb

    如何创建Cookie?

    Servlet代码

    protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        //1 创建 Cookie 对象
        Cookie cookie = new Cookie("key4", "value4"); 
        //2 通知客户端保存 Cookie 
        resp.addCookie(cookie); 
        resp.getWriter().write("Cookie 创建成功"); 
    }
    

    如果获取Cookie?

    服务器获取客户端的 Cookie 只需要一行代码:req.getCookies():Cookie[]

    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Cookie[] cookies = req.getCookies();
            for (Cookie cookie : cookies) {
                // getName方法返回Cookie的key(名)
                // getValue方法返回Cookie的value值
                resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] <br/>");
            }
    
    		// 获取指定Cookie
            Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
    
            // 如果不等于null,说明赋过值,也就是找到了需要的Cookie
            if (iWantCookie != null) {
                resp.getWriter().write("找到了需要的Cookie");
            }
        }
    

    CookieUtils工具类

    public class CookieUtils { 
        /**
          * 查找指定名称的 Cookie 对象 
          * @param name 
          * @param cookies 
          * @return 
          */ 
        public static Cookie findCookie(String name, Cookie[] cookies){ 
            if (name == null || cookies == null || cookies.length == 0) { 
                return null; 
            }
            for (Cookie cookie : cookies) { 
                if (name.equals(cookie.getName())) { 
                    return cookie;
                } 
            }return null; 
        } 
    }
    

    Cookie值的修改

    方案一
     protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        1、先创建一个要修改的同名的Cookie对象
    //        2、在构造器中,同时赋于新的Cookie值。
            Cookie cookie = new Cookie("key1","newValue1");
    //        3、调用response.addCookie( Cookie ); 通知 客户端 保存修改
            resp.addCookie(cookie);
            resp.getWriter().write("key1的Cookie已经修改好");
        }
    
    方案二
     protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        1、先查找到需要修改的Cookie对象
            Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
            if (cookie != null) {
    //        2、调用setValue()方法赋于新的Cookie值。
                cookie.setValue("newValue2");
    //        3、调用response.addCookie()通知客户端保存修改
                resp.addCookie(cookie);
            }
            resp.getWriter().write("key1的Cookie已经修改好");
        }
    

    浏览器查看Cookie

    谷歌浏览器查看Cookie

    火狐浏览器查看Cookie

    Cookie生命控制

    Cookie的销毁时间设置

    setMaxAge()

    正数,表示在指定的秒数后过期

    负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)

    零,表示马上删除 Cookie

    /**
         * 设置存活1个小时的Cooie
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Cookie cookie = new Cookie("life3600", "life3600");
            cookie.setMaxAge(60 * 60); // 设置Cookie一小时之后被删除。无效
            resp.addCookie(cookie);
            resp.getWriter().write("已经创建了一个存活一小时的Cookie");
        }
    
        /**
         * 马上删除一个Cookie
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 先找到你要删除的Cookie对象
            Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
            if (cookie != null) {
                // 调用setMaxAge(0);
                cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
                // 调用response.addCookie(cookie);
                resp.addCookie(cookie);
                resp.getWriter().write("key4的Cookie已经被删除");
            }
        }
    
        /**
         * 默认的会话级别的Cookie
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Cookie cookie = new Cookie("defalutLife","defaultLife");
            cookie.setMaxAge(-1);//设置存活时间
            resp.addCookie(cookie);
        }
    

    Cookie的Path属性可以有效的过滤哪些Cookie可以发送给服务器

    Path属性是通过请求的地址来进行有效的过滤

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        String username = req.getParameter("username"); 
        String password = req.getParameter("password");
    	if ("wzg168".equals(username) && "123456".equals(password)) { 
            //登录 成功 
            Cookie cookie = new Cookie("username", username); 
            cookie.setMaxAge(60 * 60 * 24 * 7);
            //当前 Cookie 一周内有效 
            resp.addCookie(cookie); 
            System.out.println("登录 成功"); 
        } else { 
            // 登录 失败 
            System.out.println("登录 失败"); 
        } 
    }
    

    Session

    什么是Session会话?

    • Session是一个接口(HttpSession)
    • Session是会话,用来维护一个客户端与服务器之间关联的一种技术
    • 每个客户端都有自己的一个Session
    • Session会话中,经常用来保存用户登录之后的信息

    如何创建Session和获取Session?

    创建和获取 SessionAPI 是一样的。

    request.getSession() 
    

    第一次调用是:创建 Session 会话

    之后调用都是:获取前面创建好的 Session 会话对象。

    判断到底是不是刚创建出来的(新的)

    isNew(); 
    // true 表示刚创建 
    // false 表示获取之前创建 
    

    每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。

    getId() 得到 Session 的会话 id 值

    Session域数据的存取

    /**
         * 往Session中保存数据
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.getSession().setAttribute("key1", "value1");
            resp.getWriter().write("已经往Session中保存了数据");
        }
    /**
         * 获取Session域中的数据
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Object attribute = req.getSession().getAttribute("key1");
            resp.getWriter().write("从Session中获取出key1的数据是:" + attribute);
        }
    

    Session生命周期控制

    public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁

    • 值为正数的时候,设定 Session 的超时时长
    • 负数表示永不超时(极少使用)

    public int getMaxInactiveInterval()获取 Session 的超时时间

    public void invalidate() 让当前 Session 会话马上超时无效

    Session 默认的超时时间长为 30 分钟。

    因为在 Tomcat 服务器的配置文件 web.xml中默认有以下的配置,它就表示配置了当前 Tomcat 服务器下所有的 Session

    超时配置默认时长为:30 分钟

    <session-config> 
        <session-timeout>30</session-timeout> 
    </session-config>
    

    设置个别Session的生命周期

    session.setMaxInactiveInterval(int interval)
    

    注:Session超时指的是,客户端两次请求的最大间隔时长

    eg:

    protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        // 先获取 Session 对象 
        HttpSession session = req.getSession(); 
        // 设置当前 Session3 秒后超时 
        session.setMaxInactiveInterval(3); 
        resp.getWriter().write("当前 Session 已经设置为 3 秒后超时"); 
    }
    // Session 马上被超时示例: 
    protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        // 先获取 Session 对象 
        HttpSession session = req.getSession(); 
        // 让 Session 会话马上超时 
        session.invalidate(); 
        resp.getWriter().write("Session 已经设置为超时(无效)"); 
    }
    

    Session、Cookie与浏览器关系

    Session技术底层其实是基于Cookie技术实现的

    示意图

    总结

    Cookie的工作原理

    1. 浏览器端第一次发送请求到服务器端
    2. 服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
    3. 浏览器端再次访问服务器端时会携带服务器端创建的Cookie
    4. 服务器端通过Cookie中携带的数据区分不同的用户

    Session的工作原理

    1. 浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(name为JSESSIONID的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端
    2. 浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该name为JSESSIONID的Cookie对象
    3. 服务器端根据name为JSESSIONID的Cookie的value(sessionId),去查询Session对象,从而区分不同用户
      • name为JSESSIONID的Cookie不存在(关闭或更换浏览器),重新创建Session与特殊的Cookie
      • name为JSESSIONID的Cookie存在,根据value中的SessionId去寻找session对象

    Session与Cookie区别

    session

    当你登陆一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登陆或具有某种权限。由于数据是存储在服务器上面,sessionid是服务器和客户端连接时候随机分配的,所以不能伪造

    如果浏览器使用的是cookie,那么所有数据都保存在浏览器端,比如登陆以后,服务器设置了cookie用户名,那么当再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线

    区别
    • 存储位置不同

      • cookie的数据信息存放在客户端浏览器上
      • session的数据信息存放在服务器上
    • 存储容量不同

      • 单个cookie保存的数据 <= 4KB,一个站点最多保存20个Cookie
      • 对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制
    • 隐私策略不同

      • cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的
      • session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险
    • 跨域支持上不同

      • Cookie支持跨域访问
      • Session不支持跨域访问
    人生没有白走的路,每一步都算数
  • 相关阅读:
    CentOS 8.2上安装Cassandra Web部署
    CentOS 8.2上安装Apache Cassandra 3.11.9
    CentOS 8.2使用pgAdmin安装PostgreSQL 13.1
    windows 服务器报错处理,TLS升级为1.2
    网站跳转index.html
    安装fail2ban,防止ssh爆破及cc攻击
    服务器数据盘挂载
    2条命令在centos7.5中安装谷歌浏览器
    部署安装python3.7
    部署安装snort--入侵检测工具
  • 原文地址:https://www.cnblogs.com/erhuoweirdo/p/14490982.html
Copyright © 2011-2022 走看看