【计算机网络】深入了解Cookie机制



1)什么是Cookie?

Cookie是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

  • 实际上,就是一个保存在客户机中的简单的文本文件(这个文件与特定的 Web 文档关联在一起),保存了该客户机访问这个Web 文档时的信息。
  • 注意:Cookie功能需要浏览器的支持。所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
    • 不同的浏览器采用不同的方式保存Cookie。
    • 如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。

Cookie的作用

1、客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie
2、客户端浏览器会把Cookie保存起来
3、当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。
4、服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

Cookie的内部细节

Java中把Cookie封装成了javax.servlet.http.Cookie类,每个Cookie都是该Cookie类的对象。

  • 服务器通过操作Cookie类对象对客户端Cookie进行操作。
    • 通过response.addCookie(Cookiecookie)向客户端设置Cookie
    • 通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回)
  • Cookie对象使用key-value属性对的形式保存用户状态。
    • 一个Cookie对象保存一个属性对
    • 一个request或者response同时使用多个Cookie
  • 如何查看某个网站颁发的Cookie?

    • 方法一:通过请求头查看

      在这里插入图片描述

      • 其中第一行BAIDUID记录的就是身份,只是Baidu使用特殊的方法将Cookie信息加密了。
    • 方法二:通过JS查看

      在浏览器的地址栏或者开发者工具的Console中输入javascript:alert(document.cookie) ,就会弹出你在当前网页登录的cookie信息。
      在这里插入图片描述

    • 其他方法可参考:https://blog.csdn.net/u011781521/article/details/87791125

2)Cookie是如何工作的?

2.1 Cookie的工作原理

Cookie具体的工作原理描述如下:
在这里插入图片描述

  1. Web客户端通过浏览器向Web服务器发送连接请求,通过 HTTP 报文请求行中的 URL 打开某一 Web页面。
  2. Web服务器接收到请求后,根据用户端提供的信息产生一个 Set-Cookies Head
  3. 将生成的Set-Cookies Header通过Response Header存放在HTTP报文中,回传给Web客户端,建立一次会话连接。
  4. Web客户端收到HTTP应答报文后,如果要继续已建立的这次会话,则将Cookies的内容从HTTP报文中取出,形成一个Cookies文本文件储存在客户端计算机的硬盘中,或保存在客户端计算机的内存中。
  5. 当Web客户端再次向Web服务器发送连接请求时,Web浏览器首先根据要访问站点的URL,在本地计算机上寻找对应的 Cookies文本文件(或在本地计算机的内存中寻找对应的Cookies内容)。如果找到则将此Cookies内容存放在HTTP请求报文中发给Web服务器。
  6. Web服务器接收到包含Cookies内容的HTTP请求后,检索其Cookies中与用户有关的信息,并根据检索结果生成一个客户端所请求的页面应答传递给客户端 。

2.2 服务端操作Cookie

Cookie类在javax.servlet.http.Cookie包中。

  • 添加cookie到客户端:

    // 用响应创建Cookie,等价于 response.addHeader("set-cookie", "name=value");
    Cookie cookie = new Cookie("name","value"); // 新建一个Cookie对象
    cookie.setMaxAge(seconds); // 设置Cookie的生命周期
    cookie.setPath("/"); // 设置Cookie的共享范围
    response.addCookie(cookie); // 添加cookie到客户端
    // response.addCookie(c)一旦执行,服务器端会自动发回消息头set-cookie给浏览器,set-cookie是会携带cookie键值对的,name=value。创建的cookie就会保存在浏览器。
    
Cookie常用属性
  • String name:
    该Cookie的名称。Cookie一旦创建,名称便不可更改
  • Object value:
    该Cookie的值。
    • 如果值为Unicode字符,需要为字符编码
    • 如果值为二进制数据,则需要使用BASE64编码
  • int maxAge:
    Cookie失效的时间,单位为秒(Second)。
    • <0:表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效
    • =0:表示删除该Cookie(Cookie机制没有提供删除Cookie的方法)。失效的Cookie会被浏览器从Cookie文件或者内存中删除。
    • >0:表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。是临时性Cookie,不会被持久化,不会被写到Cookie文件中。
  • String path:
    该Cookie的使用路径。
    • 如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。
    • 如果设置为“/”,则本域名下contextPath都可以访问该Cookie。
    • 注意最后一个字符必须为“/”
  • String domain:
    可以访问该Cookie的域名。
    • 如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。
    • 注意第一个字符必须为“.”
  • boolean secure:
    该Cookie是否仅被使用安全协议传输。
    • 安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。
    • 默认为false
  • 获取客户端 cookie 对象:

    // 用请求获取Cookie
    Cookie[] cookies = request.getCookies(); // 获取Cookies返回数组
    // 需遍历
    cookie.getName(); // 获取键
    cookie.getValue(); // 获取值
    
  • 修改、删除:

    // 修改Cookie
    cookie.setValue(String name); // 给当前cookie重新赋值
    
    • 修改某个Cookie时,只需要新建一个只有value属性不一样的同名Cookie,然后添加到response中覆盖原来的Cookie。
    • 删除某个Cookie时,只需要新建一个只有maxAge(设置生命周期为0)和value不一样的同名Cookie,然后添加到response中覆盖原来的Cookie。
    • 注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie而不会覆盖之前的Cookie,从而导致修改、删除失败。

2.3 JS操作Cookie

Cookie是保存在客户端的,所以浏览器可以使用脚本(JS)等操作Cookie。js操作读/写cookie的api是document.cookie

  • 读Cookie:

    console.log(document.cookie); 
    // BAIDUID=5FD734AC12FF5E5C569FE9CEAA56BD5F:FG=1; BIDUPSID=5FD734AC12FF5E5C74EC408F7EB5D4E3; PSTM=1620824022; BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; BD_HOME=1; H_PS_PSSID=33985_33822_31660_34004_33607_26350_34022; BD_UPN=13314752; BA_HECTOR=2h0lal2h01800kahng1ga1skt0q
    
    • 读取后的cookie是一个字符串,包含了所有cookie的name和value(用分号分隔),需要我们自行将cookie解析出来。
  • 写Cookie:

    document.cookie = 'uid=123;expires=Mon Jan 04 2022 17:42:40 GMT;path=/;secure;'
    document.cookie = 'uid=123;expires=Mon Jan 04 2022 17:42:40 GMT;path=/caikuai;domain=edu.360.cn;secure;samesite=lax' 
    
    • 一次只能写一个cookie,想要写多个cookie需要操作多次。
    • path默认为当前url的路径。
    • domain默认为当前访问域名。
  • expires:
    cookie过期时间。默认为session级别,页面退出时cookie失效。
  • SameSite:
    限制第三方url是否可以携带cookie(chrome51新增属性,chrome80+强制执行)。
    • Strict: 仅允许发送同站点请求的的cookie
    • Lax: 允许部分第三方请求携带cookie,即导航到目标网址的get请求
    • None: 任意发送cookie,设置为None(需要同时设置Secure,也就是说网站必须采用https)
  • HttpOnly:
    设置为true时,只有http能读取。js只能读取未设置HttpOnly的cookie。
  • Priority:
    优先级。chrome的提案(firefox不支持),定义了三种优先级,Low/Medium/High,当cookie数量超出时,低优先级的cookie会被优先清除。
  • 删除Cookie:

    只需要将一个已经存在的cookie名字过期时间设置为过去的时间即可。
    document.cookie = 'uid=dkfywqkrhkwehf23;expires=' + new Date(0) + ';path=/;secure;'
    
  • 修改Cookie:

    重新赋值就好,旧值会覆盖新值。
    • 注意:需要保证path和domain这两个值不变,否则会添加一个新的cookie。

3)cookie的共享策略

3.1 Cookie具有不可跨域名性

Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全

  • 浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名
  • Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。
  • 需要注意的是,虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie
  • 注意:用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理
  • domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径(ContextPath)。

  • domain和path共同决定了cookie可以被哪些url访问。访问一个url时,如果url的host与domain一致(或者是domain的子域名),并且url的路径与path部分匹配,那么cookie才可以被读取。

实例:url与可读取的cookie对应关系

在这里插入图片描述
假如cookie如上图所示,那么一个url与可读取的cookie对应关系为:

urluid1uid2uid3
edu.360.cn/caikuai/
edu.360.cn/×
360.cn/article/123…××
  • 跨域请求(CORS)中的cookie:

    • 首先cookie的SameSite需要设置为None。
    • 其次对于将Access-Control-Allow-Credentials设置为true的接口(表示允许发送cookie),需要我们在发送ajax请求时,将withCredentials属性设为true。

3.2 跨域请求(CORS)

3.2.1 什么是跨域请求?

跨源资源共享 Cross-Origin Resource Sharing(CORS) 是一个新的 W3C 标准,它新增的一组HTTP首部字段,允许服务端其声明哪些源站有权限访问哪些资源。换言之,它允许浏览器向声明了 CORS 的跨域服务器,发出 XMLHttpReuest 请求,从而克服 Ajax 只能同源使用的限制。

即当前发起请求的域与该请求指向的资源所在的域不一样。

  • 这里所说的域:若协议 + 域名 + 端口号均相同,那么就是同域。

​ 举个例子:

  • 假如一个域名为aaa.cn的网站,它发起一个资源路径为aaa.cn/books/getBookInfo的 Ajax请求,那么这个请求是同域的,因为资源路径的协议、域名以及端口号与当前域一致(例子中协议名默认为http,端口号默认为80)。
  • 但是,如果发起一个资源路径为bbb.com/pay/purchase的Ajax 请求,那么这个请求就是跨域请求,因为域不一致,与此同时由于安全问题,这种请求会受到同源策略限制

3.2.2 同源策略(Same-origin Policy)

同源策略是 Netscape 提出的一个著名的安全策略,是浏览器最核心最基础的安全策略,现在所有的可支持 Javascript 的浏览器都会使用这个策略。

  • DOM 层面的同源策略:
    限制了来自不同源的”Document”对象或 JS 脚本,对当前“document”对象的读取或设置某些属性。
  • Cookie和XMLHttprequest层面的同源策略:
    禁止 Ajax 直接发起跨域HTTP请求(其实可以发送请求,结果被浏览器拦截,不展示),同时 Ajax 请求不能携带与本网站不同源的 Cookie。
  • 其他详细信息可参考:https://www.jianshu.com/p/f880878c1398
*为什么需要同源策略限制?(跨域请求的安全问题)

浏览器之所以要对跨域请求作出限制,是出于安全方面的考虑,因为跨域请求有可能被不法分子利用来发动 CSRF攻击

  • *什么是CSRF攻击?

    CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

    • CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。

    CSRF攻击的原理:

    有两个网站,其中A网站是真实受信任的网站,而B网站是危险网站。
    1、在用户登陆了受信任的A网站后,本地会存储A网站相关的Cookie,并且浏览器也维护这一个Session会话。
    2、这时,如果用户在没有登出A网站的情况下访问危险网站B,那么危险网站B就可以模拟发出一个对A网站的请求(跨域请求)对A网站进行操作,而在A网站的角度来看是并不知道请求是由B网站发出来的(Session和Cookie均为A网站的),这时便成功发动一次CSRF攻击。

    • 因而 CSRF 攻击可以简单理解为:攻击者盗用了你的身份,以你的名义发送请求
    • CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…
    • 造成的问题包括:个人隐私泄露以及财产安全。

4)cookie与web安全

4.1 cookie如何应对XSS漏洞

跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

  • 什么是XSS漏洞?

    xss漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。

    • 常见的输出函数有: echo printf print print_r sprintf die var-dump var_export

  • XSS漏洞的原理:

    由于未对用户提交的表单数据或者url参数等数据做处理就显示在了页面上,导致用户提交的内容在页面上被作为html解析执行。

  • 常规方案:

    对特殊字符进行处理,如"<“和”>"等进行转义。

  • cookie的应对方案:

    对于用户利用script脚本来采集cookie信息,我们可以将重要的cookie信息设置为HttpOnly来避免cookie被js采集。

4.2 cookie如何应对CSRF攻击

CSRF,中文名叫跨站请求伪造。

  • 原理:

    用户登陆了A网站,然后因为某些原因访问了B网站(比如跳转等),B网站直接发送一个A网站的请求进行一些危险操作,由于A网站处于登陆状态,就发生了CSRF攻击。

    • 核心就是利用了cookie信息可以被跨站携带

  • 常规方案:

    采用验证码或token等。

  • cookie的应对方案:

    由于CSRF攻击核心就是利用了cookie信息可以被跨站携带,那么我们可以对核心cookie的SameSite设置为Strict或Lax来避免



【部分内容参考自】

  • Cookie的工作原理和应用详解:https://blog.csdn.net/sinat_36184075/article/details/105646140
  • Cookie详解:https://blog.csdn.net/zcl_love_wx/article/details/51992999
  • 2020最新cookie面试题汇总:https://www.cnblogs.com/qianduanpiaoge/p/14279365.html
  • 什么是跨域请求以及实现跨域的方案:https://www.jianshu.com/p/f880878c1398
  • 跨站脚本漏洞(XSS)基础讲解:https://www.jianshu.com/p/4fcb4b411a66
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值