共计 2850 个字符,预计需要花费 8 分钟才能阅读完成。
会话跟踪技术用来跟踪用户的整个会话,会话就是用户在登录网站后的一系列动作,常用的是 Cookie 和 Session,两者的唯一区别是前者在浏览器记录信息,后者在服务器。今天只是简单的说下 Cookie,知道的就算看个热闹,不知道的希望能帮到你。
以上图片是我抓包得来,从上面的图片可以看出,cookie 中的值是 key-value 格式的,而且是通过一个分号和空格来间隔的。
cookie 的流程是:服务器设置 cookie— 通过 response 将 cookie 传到前端保存在浏览器中 — 前端访问后端接口时在 request header 中自动添加上 cookie— 服务端接收到 cookie 做一些业务操作。
那么 cookie 是怎么工作的呢?首先 cookie 对于浏览器来说只是一个纯文本,浏览器的安装目录下是会有一个专门的文件夹用来保存各个网站的 cookie。当从前端发送请求到后端的时候,浏览器会自动的检测下是否有 cookie,如果有就会添加到请求的头信息中,以上是浏览器自动帮我们做的。
存储到 cookie 中的数据,浏览器会自动的放在 http 请求中,只有是每次请求都必须要发送给服务器的数据才会放到 cookie,比如身份验证信息。如果是不必要的,必然会增加网络开销。针对这个存储信息大小,cookie 还是做了一些限制的。每个域名下的 cookie 的大小最大为 4KB,每个域名下的 cookie 数量最多为 20 个(但很多浏览器厂商在具体实现时支持大于 20 个)。
cookie 的属性包括:过期时间;域名、路径等等,这些可以自己设置,如果不手动设置就会使用 cookie 的默认设置。
expires
过期时间,expires 必须是 GMT 格式的时间(可以通过 new Date().toGMTString() 或者 new Date().toUTCString() 来获得)。
如果没有设置的话,那么默认的有效期就是 session,就是会话 cookie,这种会在浏览器关掉的时候就没有了。
domain 和 path
domain 是域名,path 是路径,两者组合起来就构成了 URL,domain 和 path 一起来限制 cookie 能被哪些 URL 访问。
就是说在访问这个域名或者是该域名的子域名下,目录是在该目录或者是在该目录下的子目录下的时候,浏览器会自动把 cookie 放到请求头部中。
如果没有设置这两个选项,则会使用默认值。domain 的默认值为设置该 cookie 的网页所在的域名,path 默认值为设置该 cookie 的网页所在的目录。
两点需要注意:domain 可以设置为页面本身的域名,或者是该域名的父域名,比如说,www.sougou.com,可是设置为 www.sougou.com,也可以设置为 sougou.com。
secure
secure 选项用来设置 cookie 只在确保安全的请求中才会发送。当请求是 HTTPS 或者其他安全协议时,包含 secure 选项的 cookie 才能被发送至服务器。
默认情况下,cookie 不会带 secure 选项 (即为空)。所以默认情况下,不管是 HTTPS 协议还是 HTTP 协议的请求,cookie 都会被发送至服务端。但要注意一点,secure 选项只是限定了在安全情况下才可以传输给服务端,但并不代表你不能看到这个 cookie。
httpOnly
这个选项用来设置 cookie 是否能通过 js 去访问。默认情况下,cookie 不会带 httpOnly 选项 (即为空),所以默认情况下,客户端是可以通过 js 代码去访问(包括读取、修改、删除等)这个 cookie 的。当 cookie 带 httpOnly 选项时,客户端则无法通过 js 代码去访问操作(包括读取、修改、删除等)这个 cookie。
在客户端是不能通过 js 代码去设置一个 httpOnly 类型的 cookie 的,这种类型的 cookie 只能通过服务端来设置。
关于限制客户端去访问 cookie 的问题,这样做的目的就是为了保证安全。
试想:如果任何 cookie 都能被客户端通过 document.cookie 获取会发生什么。当我们的网页遭受了 XSS 攻击,有一段恶意的 script 脚本插到了网页中。这段 script 脚本做的事情是:通过 document.cookie 读取了用户身份验证相关的 cookie,并将这些 cookie 发送到了攻击者的服务器。攻击者轻而易举就拿到了用户身份验证信息,于是就可以利用此用户信息访问目标服务器(因为攻击者有合法的用户身份验证信息,所以会通过你服务器的验证)。
下面的这段是从项目中找到的一段关于设置 cookie 的代码:
public void addCookie(HttpServletResponse response, String cookieValue) {
if (this.cookieDomain == null) {
throw new IllegalArgumentException(“cookies domain is not null”);
} else {
Cookie cookie = new Cookie(this.coookieName, cookieValue);
cookie.setPath(this.cookiePath);
if (this.cookieDomain != null) {
cookie.setDomain(this.cookieDomain);
}
if (this.cookieMaxAge != null) {
cookie.setMaxAge(this.cookieMaxAge);
}
if (this.cookieSecure) {
cookie.setSecure(true);
}
if (this.cookieHttpOnly) {
cookie.setHttpOnly(true);
}
response.addCookie(cookie);
}
}
什么时候 cookie 会被覆盖:cookie 中的 name、domain、path 这 3 个字段数值都相同的时候。
如果显式设置了 domain,则设置成什么,浏览器就存成什么;但如果没有显式设置,则浏览器会自动取 url 的 host 作为 domain 值;
修改 cookie。
要想修改一个 cookie,只需要重新赋值就行,旧的值会被新的值覆盖。但要注意一点,在设置新 cookie 时,path、domain 这两个字段一定要和之前保持一样。否则是不会确定为之前的 cookie,而是添加了一个新的 cookie。
删除 cookie
删除一个 cookie 也是一样的,也是重新赋值,只要将这个新 cookie 的 expires 选项设置为一个过去的时间点或者是直接赋值为 0 就行了。但同样要注意,path 和 domain 同样需要和之前的 cookie 保持一致。
在开发的过程中,用户的登录态是大部分是放到 cookie 里,因为 cookie 自己有着完整的一套配置,包括上文讲到的各种属性和安全问题,总体来说还是比较方便的。
东西不多,也很简单,希望每个读者都能完全消化。
这样的分享会一直持续,你的关注、转发和点赞是对我最大的支持,感谢。