localStorage、sessionStorage、cookit、session

1,211 阅读8分钟

一:cookit

1)cookit是什么?

是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。

2)创建Cookie

当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie选项。浏览器收到响应后通常会保存下Cookie,之后对该服务器每一次请求中都通过Cookie方式将Cookie信息发送给服务器。

3)时效性
  • 如果在Set-Cookie时不通过ExpriesMax-Age两个字段设置Cookie的时效性,那么这个Cookie是一个简单的会话期Cookie。它在关闭浏览器是会被自动删除。
  • 如果设置了ExpriesMax-Age那么这个Cookie在指定时间内都是有效的。 注意: 提示:当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。
5)作用域

Domain Path 标识定义了Cookie的作用域:即Cookie应该发送给哪些URLDomain 标识指定了哪些主机可以接受Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domain,则一般包含子域名。

Path 标识指定了主机下的哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。以字符%x2F ("/")作为路径分隔符,子路径也会被匹配。

6)存储大小
  • cookie:单个cookie保存的数据不能超过4kb
  • session大小没有限制。
7)cookie的特点

优点:

  • 储存用户信息(用户token)
  • 标记用户行为(uuid、埋点) 缺点:
  • Cookie会被附加在每个HTTP请求中,所以无形中增加了流量
  • Cookie可能被禁用。当用户非常注重个人隐私保护时,他很可能禁用浏览器的Cookie功能;
  • 由于在HTTP请求中的Cookie是明文传递的,潜在的安全风险,Cookie 可能会被篡改
  • 每个Cookie长度不能超过4KB
8)cookie安全问题

<1>: xss 和 防御xss

  • xss(跨站脚本攻击): 恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,因此会达到恶意攻击用户的目的。

  • 预防:

    • cookie安全策略服务器端设置cookie的时候设置 http-only, 这样就可以防止用户通过JS获取cookie cookie的读写或发送一般有如下字段进行设置:
    1. http-only: 只允许httphttps请求读取cookieJS代码是无法读取cookie的(document.cookie会显示http-onlycookie项被自动过滤掉)。发送请求时自动发送cookie.
    2. secure-only: 只允许https请求读取,发送请求时自动发送cookie
    3. host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie
    • XSS防御HTML编码 编码规则:将 & < > " ' / 转义为实体字符。如下基本转义代码:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset=utf-8>
      <meta name="referrer" content="never">
      <title></title>
    </head>
    <body>
      <script type="text/javascript">
        // 使用正则表达式实现html编码
        function htmlEncodeByRegExp(str) {
          var s = '';
          if (str.length === 0) {
            return s;
          }
          return (s + str)
            .replace(/&/g, "&")
            .replace(/</g, "<")
            .replace(/>/g, ">")
            .replace(/ /g, " ")
            .replace(/\'/g, "&#39")
            .replace(/\"/g, """)
            .replace(/\//g, '&#x2F;');
        }
        // 使用正则表达式实现html解码
        function htmlDecodeByRegExp(str) {
          var s = '';
          if (str.length === 0) {
            return s;
          }
          return (s + str)
            .replace(/&/g, "&")
            .replace(/</g, "<")
            .replace(/>/g, ">")
            .replace(/ /g, " ")
            .replace(/&#39/g, "\'")
            .replace(/"/g, "\"")
            .replace(/&#x2F;/g, "\/");
        }
    
        // 测试代码:
        var html = '<br>aaaaaa<p>xxxxxx</p>';
        var encodeHtml = htmlEncodeByRegExp(html);
        // 输出:使用正则表达式对html编码:<br>aaaaaa<p>xxxxxx<&#x2F;p>
        console.log("使用正则表达式对html编码:" + encodeHtml);
        var decodeHtml = htmlDecodeByRegExp(encodeHtml);
    
        // 输出:使用正则表达式对html解码:<br>aaaaaa<p>xxxxxx</p>
        console.log("使用正则表达式对html解码:" + decodeHtml);
    
      </script>
    </body>
    </html>
    
    • XSS 防御HTML Attribute编码
    • XSS防御之javascript编码 <2>csrf 和 csrf防御
  • CSRF: 跨站请求伪造(CSRF)是一种冒充受信任用户,向服务器发送非预期请求的攻击方式 CSRF(Cross-site Request Forgery), 中文名字叫:跨站请求伪造。那么什么是跨站请求 伪造呢?就是用户登录一个正常的网站后,由于没有退出该正常网站,cookie信息还保留,然 后用户去点击一个危险的网站页面,那么这个时候危险网站就可以拿到你之前登录的cookie信息。然后使用cookie信息去做一些其他事情

  • CSRF 防范措施

    • strict:浏览器在任何跨域请求中都不会携带Cookie,这样可以有效的防御CSRF攻击,但是对于有多个子域名的网站采用主域名存储用户登录信息的场景,每个子域名都需要用户重新登录,造成用户体验非常的差。
    • 设置cookie有效期时间
    • 防止cookie是明文,服务器端生成密钥验证
    • 生成随机数和cookie发送给服务器端

二:Session

1)什么是session?

Session 代表着服务器和客户端一次会话的过程

2)创建session

Session在用户第一次访问服务器的时候自动创建。 需要注意只有访问JSPServlet等程序时才会创建Session, 只访问HTMLIMAGE等静态资源并不会创建Session。 如果尚未生成Session,也可以使用request.getSession(true)强制生成Session

第一次创建 Session 的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个 SessionID,以后每次请求都把这个会话ID发送给服务器,我就知道你是谁了。 session 的运行依赖 SessionID,而 SessionID 是存在cookie中的。

3)Session的有效期

由于会有越来越多的用户访问服务器,因此Session也会越来越多。 为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。 这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

  • Session的超时时间为maxInactiveInterval属性, 可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。

  • Session的超时时间也可以在web.xml中修改。 另外,通过调用Sessioninvalidate()方法可以使Session失效。 三种方法让Session失效:

  • 服务器意外关闭。(服务器正常关闭时session是会被服务器保存在服务器的 session.ser 文件中(在work文件夹下))

  • session自杀: 调用session.invalidate()方法可以立即杀死session

  • 可以在服务器下的web.xml文件中的<session-timeout> 30 </session-timeout>修改这是默认值(默认30分钟),是以分为单位。 。

4)浏览器关闭session会失效?
  • 为什么会失效?
    • 在服务器端生成session,并且把sessionid通过set-cookie发送给浏览器 以后每次请求除了图片、静态文件请求,其它的请求都会带上服务端写入浏览器中cookie
    • 服务端接收到sessionid,通过sessionid找到对应的session信息
    • 当浏览器关闭时,当前域名中设置的cookie会被清空
    • 再下次请求使,服务端接收到的sessionnull,服务端就会认为当前用户是一个新的用户,重新登录或者直接设置新的sessionid

上面也就是为什么会说session会在浏览器关闭时会失效。

  • 怎么能让它不失效?

    • Set-Cookie时设置ExpriesMax-Age,其实就是设置Cookie的失效时间。 或者直接把Sessionid储存在本地。

三:web Storage

Web Storage API提供机制, 使浏览器能以一种比使用Cookie更直观的方式存储键/值对。 Web Storage 包含如下两种机制:

  • sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
  • localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。
1)相同点
  • 存储大小一般均为5M左右
  • 都有同源策略限制,跨域无法访问
  • 数据仅在客户端中保进行存储,并不参与和服务器的通信(不会随着 http 请求发送到服务器)
  • keyvalue 的形式进行存储数据, value 值必须为字符串,不为字符串会自动转型( value 如果是对象则需要转为 json 进行存储)
2)不相同点
  • 生命周期

    • localStorage 存储的数据是永久性的,除非用户人为删除否则会一直存在(调用 localStorage api 或则清除浏览器数据)。

    • sessionStorage 存储的数据在当前会话结束时会被清除,一旦窗口或者标签页被关闭,那么所有通过 sessionStorage 存储的数据也会被删除。

  • 作用域

    • localStorage: 在同一个浏览器内,同源文档之间共享 localStorage 数据,可以互相读取、覆盖、清除(同浏览器限制、同源限制)

    • sessionStorage: 与 localStorage 一样需要同一浏览器同源文档这一条件。除此之外 sessionStorage 的作用域还被限定在了窗口中,也就是说,只有同一浏览器、同一窗口的同源文档才能共享数据(同浏览器限制、同源限制、同标签页限制)

3)操作

sessionStorage localStorage 在操作上没什么区别,下面以 sessionStorage 为例:

  • 新增、修改

    • 通过 setItem 添加、修改数据
    sessionStorage.setItem('name', 'qianyin');
    sessionStorage.setItem('name', 'linheng');
    sessionStorage.setItem('user1', {name: 'qianyin'});
    sessionStorage.setItem('user2', JSON.stringify({name: 'qianyin'}));
    
    
    • 通过对象的形式添加、修改数据
    sessionStorage.name = 'qianyin';
    sessionStorage.name = 'linheng';
    sessionStorage.user1 = {name: 'qianyin'};
    sessionStorage.user2 = JSON.stringify({name: 'qianyin'})
    
    
  • 获取数据

    • 通过 getItem 获取数据
    sessionStorage.getItem('user')
    
    
    • 通过对象的形式获取数据
    sessionStorage.user
    
  • 移除数据

    • 通过 removeItem 移除指定数据
    sessionStorage.removeItem('user');
    
    • 通过对象的形式移除指定数据
    delete sessionStorage.user
    
    
    • 移除当前作用域下所有数据
    sessionStorage.clear();