cookie

2020/03/20 功能实现

本地有效期存储数据

记录 cookie 的概念,设置获取删除

http 里面协议是没有状态的,每一次 http 请求都是独立的无关的。 但是在 web 应用中,多个请求之间共享会话是非常必要的,所以 cookie 是为了辨别用户身份,进行会话跟踪而存储在 客户端上的数据。向同一个域名下发送请求,都会携带像他的 Cookie,服务器拿到它之后会进行解析,相当于拿到了客户端的状态

第一次客户端向服务器发送请求的时候,服务器就会通过响应头 Set-Cookie 向客户端种植 Cookie。以后客户端再向服务器发起请求的时候会带上 Cookie 服务器通过读取请求头中的 cookie 进行响应。但是这个有一点不安全,客户端可以修改 Cookie 的值,导致下次服务器读取到了错误客户端的 Cookie 的值,获取不到用户信息。为了防止 cookie 信息被修改,我们可以进行对 cookie 进行签名防止串改

设置 cookie : document.cookie=newCookie,一次只能只能对一个 cookie 进行操作,newCookie 后面的可选参数有 ;path='cookie的路径,只有路径匹配才能读到,只匹配前缀';domain='在哪一个域名下可以访问';max-age=max-age-in-seconds最大存活时间相对时间;expires=date-inGMTSting-format过期时间,绝对时间;httpOlony=true只能通过 HTTP 协议传输,不能通过 JS 访问,这也是预防 XSS 攻击的重要手段。;SameSite='Strict' 或者是自定义

SameSite 可以设置为三个值,StrictLaxNone 。 a. 在 Strict 模式下,浏览器完全禁止第三方请求携带 Cookie 。比如请求 sunseekers.cn 网站只能在 sunseekers.cn 域名当中请求才能携带 Cookie,在其他网站请求都不能。

b. 在 Lax 模式,就宽松一点了,但是只能在 get 方法提交表单况或者 a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。

c. 在 None 模式下,也就是默认模式,请求会自动携带上 Cookie

设置 cookie: 原理是根据文档要求直接赋值操作,注意了,一次只能设置一个 cookie,不能操作多个 cookie

function setCookie(name,value,exdays){
  const now = new Date()
  now.setTime(now.getTime()+(exdays*24*60*60*1000))
  const expires = `expires=${now.toUTCString}`//toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。
  console.log(expires);// 如果没有设置过期时间,默认浏览器关闭的时候清除 cookie,
  document.cookie=`${name}=${value}; ${expires}`
}

读取 cookie: 原理是利用 cookie 存储的规则,进行字符串的切割获取

function getCookie(name){
  const cname = `${name}=`
  const cookie = document.cookie.split(';')
  for(let i=0;i<cookie.length;i++){
    let cookieVal = cookie[i]
    while(cookieVal.charAt(0)===' ') cookieVal = cookieVal.substring(1)
    if(cookieVal.indexOf(cname)!=-1) return cookieVal.substring(cname.length, cookieVal.length);
  }
  return ''
}

清除 cookie: 原理是利用一个已经过期的时间,自动清除 cookie

function clearCookie(name){
  setCookie(name,"",-1)
}

注意了:

chrome 浏览器在本地获取不到 cookie。必须在服务器上才可以。如果是本地的话,你可以放到 localwww 目录下面。

Google Chrome 只支持在线网站的 cookie 的读写操作,对本地 htmlcookie 操作是禁止的。所以下面的代码如果你写在一个本地的 html 文件中,将弹出的对话框内容为空。

如果我们设置了新的 cookie ,旧的 cookie 不会被覆盖,只是将新的添加到 document.cookie 中.

node 进行客户端种植 cookie ,实现原理很简单,就是在响应体里面加一个 Set-Cookie 字段就够了

const http = require('http')
const serve = http
  .createServer((req, res) => {
    if (req.url === '/write') {
      res.setHeader('Set-Cookie', 'name=sunseekers')
      res.end('write cookie ok')
    } else if (req.url === '/read') {
      let cookie = req.headers['cookie']
      res.end(cookie)
    } else {
      res.end('not found')
    }
  })
  .listen(8888)

可能被客户端篡改,使用前验证合法性,因为数据在客户端保存,服务器没有保存 不要存储敏感数据,比如用户密码,账户余额 使用 httpOnly 保证安全 尽量减少 cookie 的体积,限制了 64k 设置正确的 domainpath,减少数据传输 ,只有匹配上的时候才会发送到服务器

session

是一种记录客户端状态/数据的一种机智,只是他是保存在服务端的,客户端访问服务器的时候,服务器会以某一种形式记录在服务器上。这样比客户端会安全很多,浏览器无法修改,但是他会占用服务器的性能,如果数据量多的话

简单说就是,session 会生成一个唯一的表识符给客户端,服务端根据这个唯一的表识符存储数据。下次客户端通过请求头中的 cookie 把唯一的表识符发送给服务器,服务器根据这个唯一的表识符去读取数据

参考资料

JS 设置 cookie,删除 cookie Document.cookie 浏览器系列之 Cookie 和 SameSite 属性


有时候,虽然素未谋面。却已相识很久,很微妙也很知足。在逝去的岁月里,我们在某一刻,共同经历着一样的情愫。

如果喜欢我的话,我们可以互相关注,相互学习的哟!互相鼓励,你的关注是我最大的动力来源

sunseekers

Search

    Table of Contents