4

1、cookie是什么

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。如下图:
图片描述

1.1、cookie的属性

属性项 属性项介绍
Name 一个唯一确定cookie的名称(cookie名称不区分大小写,实践中最好区分,因为一些服务器会区分),URL编码
Value 存储cookie的字符串值,值必须经过URL编码
Expires 过期时间,在这个时间点后Cookie失效
Domain 生成Cookie域名
Path 该Cookie是在当前那个路径下生成的
Secure 加密设置,设置他之后,只会在SSL连接时才会回传该Cookie

图片描述
这里我只要说二个点:
1、Expires:该Cookie失效的时间,单位秒。

  • 如果为正数,则该Cookie在maxAge秒之后失效(持久级别Cookie)。
  • 如果为负数,该Cookie为临时Cookie,关闭浏览器即失效(会话级别Cookie),浏览器也不会以任何形式保存该Cookie。
  • 如果为0,表示删除该Cookie。默认为–1;

2、Domain:
我们现在有二个域名。域名A:b.f.com,域名B:d.f.com;显然域名A和域名B都是f.com的子域名

  • 如果我们在域名A中的Cookie的domain设置为.f.com,那么.f.com及其子域名都可以获取这个Cookie,即域名A和域名B都可以获取这个Cookie

如果域名A没有显式设置Cookie的domain方法,那么domain就为.b.f.com,不一样的是,这时,域名A的子域名将无法获取这个Cookie

HttpOnly: 这个属性是面试的时候常考的,如果这个属性设置为true,就不能通过js脚本来获取cookie的值,能有效的防止xss攻击

1.2、cookie的操作

由于js没有给原生的操作方法,我们可以简单地封装一下:

var cookieUtil = {
    getItem: function (name) {
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null;
        if (cookieStart > -1) {
            var cookieEnd = document.cookie.indexOf(';', cookieStart);
            if (cookieEnd == 1) {
                cookieEnd = document.cookie.length;
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd))
        }
        return cookieValue;
    },
    setItem: function (name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        if (expires) {
            cookieText += ";expires=" + expires.toGMTString();
        }
        if (path) {
            cookieText += ";path=" + path;
        }
        if (domain) {
            cookieText += ";domain=" + domain;
        }
        if (secure) {
            cookieText += ";secure";
        }
        document.cookie = cookieText;
    },
    unset: function (name, path, domain, secure) {
        this.setItem(name, "", new Date(0), path, domain, secure)
    }
}
CookieUtil.setItem("name", 'tom'); // 设置cookie
console.log(CookieUtil.getItem('name'));//读取cookie
CookieUtil.unset("name")//删除cookie

1.3、Cookie防篡改机制

因为Cookie是存储在客户端,用户可以随意修改。所以,存在一定的安全隐患。

防篡改签名:服务器为每个Cookie项生成签名。如果用户篡改Cookie,则与签名无法对应上。以此,来判断数据是否被篡改。

原理如下:

  • 服务端提供一个签名生成算法secret
  • 根据方法生成签名secret(wall)=34Yult8i
  • 将生成的签名放入对应的Cookie项username=wall|34Yult8i。其中,内容和签名用|隔开。
  • 服务端根据接收到的内容和签名,校验内容是否被篡改。

举个栗子:
比如服务器接收到请求中的Cookie项username=pony|34Yult8i,然后使用签名生成算法secret(pony)=666。 算法得到的签名666和请求中数据的签名不一致,则证明数据被篡改。

2、Session

Session: 是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中.为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

当客户端请求创建一个session的时候,服务器会先检查这个客户端的请求里是否已包含了一个session标识 - sessionId,

  • 如果已包含这个sessionId,则说明以前已经为此客户端创建过session,服务器就按照sessionId把这个session检索出来使用(如果检索不到,可能会新建一个)
  • 如果客户端请求(一般是通过cookie携带)不包含sessionId,则为此客户端创建一个session并且生成一个与此session相关联的sessionId

sessionId的值一般是一个既不会重复,又不容易被仿造的字符串,这个sessionId将被在本次响应中返回给客户端保存。保存sessionId的方式大多情况下用的是cookie。

session 的运行依赖 session id,而 session id 是存在 cookie中的

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

3、cookie与session的区别

cookie session
存储位置 客户端 服务器端
存取方式 只能保管ASCII字符串 够存取任何类型的数据
有效期不同 Cookie可以设置过期时间属性 JSESSIONID的过期时间默许为–1,只需关闭了阅读器该Session就会失效
服务器压力 Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择 Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存
跨域支持上的不同 Cookie支持跨域名访问,例如将domain属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。 Session则不会支持跨域名访问。Session仅在他所在的域名内有效。
区分路径 cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的 session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star对作者也是一种鼓励。

参考
Cookie防篡改机制
彻底理解cookie,session,token


Alan
1.5k 声望1.7k 粉丝

青青子衿,悠悠我心。


引用和评论

0 条评论