• 浅谈 cookie 和 session


    1.cookie适合存储的数据:每次请求都要携带的信息就很适合放在cookie中

    存储cookie是浏览器提供的功能,cookie其实是存储在浏览器中的纯文本,浏览器的安装目录下会专门有一个cookie文件夹来存放各个域下设置的cookie。
    当网页要发http请求时,浏览器会先检查是否有相应的cookie,有则自动添加在request Header中的cookie字段中,这些是浏览器自动帮我们做的,而且每一次http请求浏览器都会自动帮我们做。如果这些数据并不是每个请求都需要发给服务端的数据,浏览器的这个自动处理无疑增加了网络开销;但如果这些数据是每个请求都需要发给服务器的数据(比如身份认证信息),浏览器这设置自动处理就大大免去了重复添加操作。对于每次请求都要携带的信息就很适合放在cookie中,其他类型的不适合。

    2.cookie的获取

    JS原生的API提供的获取cookie方法:document.cookie(该方法只能获取HttpOnly类型的cookie)。打印的结果是一个字符串类型,因为cookie本身就是存储在浏览器中的字符串,但这个字符串是有格式的,由键值对key=value构成,键值对之间由一个分号和一个空格隔开

    3.cookie的组成

    每个cookie都有一定的属性,如失效时间、发送到的域名、哪个路径等。这些属性是通过cookie选项来设置的,cookie选项包括:expires,domain,path,secure,HttpOnly。在设置任一个cookie时都可以设置相关的这些属性,当然也可以不设置直接使用默认值。在设置这些属性时,属性之间由一个分号和一个空格隔开。

    "key=name; expires=Thu, 25 Feb 2016 04:18:00 GMT; domain=ppsc.sankuai.com; path=/; secure; HttpOnly"

    3.1. expires:选项用来设置“cookie 什么时间内有效”。expires其实是cookie失效日期,expires必须是 GMT 格式的时间(可以通过 new Date().toGMTString()或者 new Date().toUTCString() 来获得)

    如expires=Thu, 25 Feb 2016 04:18:00 GMT表示cookie讲在2016年2月25日4:18分之后失效,对于失效的cookie浏览器会清空。如果没有设置该选项,则默认有效期为session,即会话cookie。这种cookie在浏览器关闭后就没有了。

    expires 是 http/1.0协议中的选项,在新的http/1.1协议中expires已经由 max-age 选项代替,两者的作用都是限制cookie 的有效时间。expires的值是一个时间点(cookie失效时刻= expires),而max-age 的值是一个以为单位时间段(cookie失效时刻= 创建时刻+ max-age)。
    另外,max-age 的默认值是 -1(即有效期为 session );若max-age有三种可能值:负数、0、正数。负数:有效期session0:删除cookie;正数:有效期为创建时刻+ max-age

    3.2.domain 和 path

    domain是域名,path是路径,两者加起来就构成了 URL,domainpath一起来限制 cookie 能被哪些 URL 访问。

    一句话概括:某cookie的 domain为“baidu.com”, path为“/ ”,若请求的URL(URL 可以是js/html/img/css资源请求,但不包括 XHR 请求)的域名是“baidu.com”或其子域如“api.baidu.com”、“dev.api.baidu.com”,且 URL 的路径是“/ ”或子路径“/home”、“/home/login”,则浏览器会将此 cookie 添加到该请求的 cookie 头部中。

    所以domainpath2个选项共同决定了cookie何时被浏览器自动添加到请求头部中发送出去。如果没有设置这两个选项,则会使用默认值。domain的默认值为设置该cookie的网页所在的域名,path默认值为设置该cookie的网页所在的目录。

        特别说明1:
        发生跨域xhr请求时,即使请求URL的域名和路径都满足 cookie 的 domain 和 path,默认情况下cookie也不会自动被添加到请求头部中。)
    
        特别说明2:
        domain是可以设置为页面本身的域名(本域),或页面本身域名的父域,但不能是公共后缀 public suffix。举例说明下:如果页面域名为 www.baidu.com, domain可以设置为“www.baidu.com”,也可以设置为“baidu.com”,但不能设置为“.com”或“com”。

    3.3.secure

    secure选项用来设置cookie只在确保安全的请求中才会发送。当请求是HTTPS或者其他安全协议时,包含 secure 选项的 cookie 才能被发送至服务器。

    默认情况下,cookie不会带secure选项(即为空)。所以默认情况下,不管是HTTPS协议还是HTTP协议的请求,cookie 都会被发送至服务端。但要注意一点,secure选项只是限定了在安全情况下才可以传输给服务端,但并不代表你不能看到这个 cookie。

    如果想在客户端即网页中通过 js 去设置secure类型的 cookie,必须保证网页是https协议的。在http协议的网页中是无法设置secure类型cookie的。

    3.4.httpOnly

    这个选项用来设置cookie是否能通过 js 去访问。默认情况下,cookie不会带httpOnly选项(即为空),所以默认情况下,客户端是可以通过js代码去访问(包括读取、修改、删除等)这个cookie的。当cookiehttpOnly选项时,客户端则无法通过js代码去访问(包括读取、修改、删除等)这个cookie

    在客户端是不能通过js代码去设置一个httpOnly类型的cookie的,这种类型的cookie只能通过服务端来设置。

    通过document.cookie是不能获取的。

    ——httpOnly与安全
    
    从上面介绍中,大家是否会有这样的疑问:为什么我们要限制客户端去访问cookie?其实这样做是为了保障安全。
    
    试想:如果任何 cookie 都能被客户端通过document.cookie获取会发生什么可怕的事情。当我们的网页遭受了 XSS 攻击,有一段恶意的script脚本插到了网页中。
    这段script脚本做的事情是:通过document.cookie读取了用户身份验证相关的 cookie,并将这些 cookie 发送到了攻击者的服务器。攻击者轻而易举就拿到了用户身份验证信息,于是就可以摇摇大摆地冒充此用户访问你的服务器了(因为攻击者有合法的用户身份验证信息,所以会通过你服务器的验证)。

    4.cookie的设置

    cookie既可以由服务端来设置,也可以由客户端来设置。

    不管你是请求一个资源文件(如 html/js/css/图片),还是发送一个ajax请求,服务端都会返回response。而response header中有一项叫set-cookie,是服务端专门用来设置cookie的。如下图所示,服务端返回的response header中有5个set-cookie字段,每个字段对应一个cookie(注意不能将多个cookie放在一个set-cookie字段中),set-cookie字段的值就是普通的字符串,每个cookie还设置了相关属性选项。

    4.1.js设置cookie

    document.cookie = "name=mist"

    浏览器显示:

    4.2. 修改cookie

    要想修改一个cookie,只需要重新赋值就行,旧的值会被新的值覆盖。但要注意一点,在设置新cookie时,path/domain这几个选项一定要旧cookie 保持一样。否则不会修改旧值,而是添加了一个新的 cookie。

    name/domain/path 这3个字段都相同的时候,cookie 会被覆盖

    4.3. 删除cookie

    删除一个cookie 也挺简单,也是重新赋值,只要将这个新cookie的expires 选项设置为一个过去的时间点就行了。但同样要注意,path/domain/这几个选项一定要旧cookie 保持一样。

    4.3. cookie编码

    cookie其实是个字符串,但这个字符串中逗号、分号、空格被当做了特殊符号。所以当cookie的 key 和 value 中含有这3个特殊字符时,需要对其进行额外编码,一般会用escape进行编码,读取时用unescape进行解码;当然也可以用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI

    5.跨域请求中的cookie

    默认情况下,在发生跨域时,cookie 作为一种 credential 信息是不会被传送到服务端的。必须要进行额外设置才可以。

    1.关闭浏览器后,session是否还存在?

    session在服务器和客户端各保留一个副本,关闭浏览器与否和session是否存在没有任何关系.

    session采取的是服务器端保持状态的方案,它存储在内存里,当服务器进程被停止或者重启的时候,内存里的session也会被清空,如果设置了session的持久化特性,服务器会把session保存到硬盘上,当服务器进程被重新启动时这些信息将被再次使用.

    2.开两个浏览器窗口访问应用程序会使用用一个session还是不同的session?

    两个不同的.

    3.cookie机制和session机制的区别和联系?

    cookie机制采用在客户端保持状态的方案.cookie的作用是为了弥补http无状态的缺陷.是保存在本机的文件,记录短小的信息,除非cookie过期,否则会一直在.

    session机制采用在服务器端保持状态的方案.由于采用服务器端保持状态的方案在客户端也需要保存一个标志,所以session机制可能要cookie机制来达到保存标志的目的.session是私有的每个客户端都存在不同的session生存期,正常是20分钟,可自己设定.

  • 相关阅读:
    nginx+tomcat负载均衡
    一个tomcat部署多个应用实例
    多级菜单存在同一张表,一次性把所有关系取出来
    关于ajax post请求,参数过大产生的问题解决 Java
    nginx 的 proxy_cache 缓存配置
    nginx 安装 lua_nginx_module 模块(nginx——lua 学习笔记1)
    nginx 反向代理
    nginx的共享字典项api(操作方法)
    sed 常用命令 网址
    Django之 数据库ORM
  • 原文地址:https://www.cnblogs.com/miaoying/p/4948662.html
Copyright © 2020-2023  润新知