cookie
cookie基本介绍
Cookie 用于存储 web 页面的用户信息。 Cookie 是一些数据, 存储于你电脑上的文本文件中。 当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。 Cookie 的作用就是用于解决 “如何记录客户端的用户信息”。 当用户访问 web 页面时,他的名字可以记录在 cookie 中。 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。 当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。
使用 JavaScript 创建Cookie
JavaScript 中,创建 cookie 如下所示: document.cookie=”username=John Doe”;
您还可以为 cookie 添加一个过期时间(以 UTC 或 GMT 时间)。默认情况下,cookie 在浏览器关闭时删除: document.cookie=”username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT”;
您可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。 document.cookie=”username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/”;
能设置或读取子域的cookie吗?
- 不行! 只能向当前域或者更高级域设置cookie
- 例如 client.com 不能向 a.client.com 设置cookie, 而 a.client.com 可以向 client.com 设置cookie, 读取cookie情况同上。
客户端设置cookie与服务端设置cookie有什么区别?
-
无论是客户端还是服务端, 都只能向自己的域或者更高级域设置cookie 例如 client.com 不能向 server.com 设置cookie, 同样 server.com 也不能向 client.com 设置cookie
- 服务端可以设置 httpOnly: true, 带有该属性的cookie客户端无法读取
- 客户端只会带上与请求同域的cookie, 例如 client.com/index.html 会带上 client.com 的cookie, server.com/app.js 会带上 server.com 的cookie, 并且也会带上httpOnly的cookie
- 但是, 如果是向服务端的ajax请求, 则不会带上cookie, 详情见第三个问题
同域/跨域ajax请求到底会不会带上cookie?
- 这个问题与你发起ajax请求的方式有关
- fetch在默认情况下, 不管是同域还是跨域ajax请求都不会带上cookie。
- 只有当设置了 credentials 时才会带上该ajax请求所在域的cookie
- 服务端需要设置响应头 Access-Control-Allow-Credentials: true, 否则浏览器会因为安全限制而报错, 拿不到响应
fetch 设置 credentials
- 使fetch带上cookie
fetch(url, { credentials: "include", // include, same-origin, omit })
- include: 跨域ajax带上cookie
- same-origin: 仅同域ajax带上cookie
- omit: 任何情况都不带cookie
axios 设置 withCredentials
- 使axios带上cookie
- axios.get(‘http://server.com’, {withCredentials: true})
jQuery 设置 withCredentials
$.ajax({ method: 'get', url: 'http://server.com', xhrFields: { withCredentials: true } })
为什么Cookie需要防篡改
- 为什么要做Cookie防篡改,一个重要原因是
- Cookie中存储有判断当前登陆用户会话信息(Session)的会话票据-SessionID和一些用户信息。
- 当发起一个HTTP请求,HTTP请求头会带上Cookie,Cookie里面就包含有SessionID。
- 后端服务根据SessionID,去获取当前的会话信息。如果会话信息存在,则代表该请求的用户已经登陆。
- 服务器根据登陆用户的权限,返回请求的数据到浏览器端。
- 因为Cookie是存储在客户端,用户可以随意修改。所以,存在一定的安全隐患。
防篡改签名
-
服务器为每个Cookie项生成签名。如果用户篡改Cookie,则与签名无法对应上。以此,来判断数据是否被篡改。
- 原理: 服务端提供一个签名生成算法secret
- 根据方法生成签名secret(wall)=34Yult8i
-
将生成的签名放入对应的Cookie项username=wall 34Yult8i。其中,内容和签名用 隔开。 - 服务端根据接收到的内容和签名,校验内容是否被篡改。
*比如服务器接收到请求中的Cookie项username=pony | 34Yult8i,然后使用签名生成算法secret(pony)=666。算法得到的签名666和请求中数据的签名不一致,则证明数据被篡改。 |
敏感数据的保护
- 鉴于Cookie的安全性隐患,敏感数据都应避免存储在Cookie。应该根据SessionID,将敏感数据存储在后端。取数据时,根据SessionID去后端服务器获取即可。
- 另外,对一些重要的Cookie项,应该生成对应的签名,来防止被恶意篡改。