了解 node cookie 状态保持

cookie

在浏览器端,cookie实际上是一些小文件,可以持久的保存一些数据,通常用它来保存token

浏览器可以保存很多的cookie,每个cookie包含下面的信息:

  • key:键
  • value:值
  • domain:域,表达这个cookie是属于哪个网站的,比如duyi.ke.qq.com,表示这个cookie是属于duyi.ke.qq.com这个网站的
  • path:路径,表达这个cookie是属于该网站的哪个基路径的。比如/news,表示这个cookie属于/news这个路径的。
  • secure:是否使用安全传输,跟https协议相关,本文不涉及
  • expire:过期时间,表示该cookie在什么时候过期

设置cookie

当服务器响应浏览器时,可以在消息头中添加一个特殊的字段set-cookie,当浏览器发现响应头中包含set-cookie时,会自动根据它的值设置cookie

比如,服务器的响应头中包含下面的内容:

set-cookie: a=1; domain=localhost; expire=Thu, 29 May 2020 06:33:03 GMT

表示设置一个cookie,它的名称是a,值是1,域是localhost,过期时间是格林威治时间 2020-05-29 06:33:03

设置cookie的完整格式是:

键=值; path=?; domain=?; expire=?; max-age=?; secure; httponly
  • path:设置cookie的路径。如果不设置,浏览器会将其自动设置为当前请求的基路径。比如,浏览器请求的path/api/user/login,服务器响应了一个set-cookie: a=1,浏览器会将该cookie的path设置为请求的路径/api/user

  • domain:设置cookie的域。如果不设置,浏览器会自动将其设置为当前的请求域,比如,浏览器请求的地址是http://test.qq.com/api/user/login,服务器响应了一个set-cookie: a=1,浏览器会将该cookie的domain设置为请求的域test.qq.com

    • 这里值得注意的是,如果服务器响应了一个无效的域,浏览器是不认的
    • 什么是无效的域?就是响应的域连根域都不一样。比如,浏览器请求的域是duyi.ke.qq.com,服务器响应的cookie是set-cookie: a=1; domain=baidu.com,这样的域浏览器是不认的。
    • 如果浏览器连这样的情况都允许,就意味着张三的服务器,有权利给用户一个cookie,用于访问李四的服务器,这会造成很多安全性的问题
  • expire:设置cookie的过期时间。这里必须是一个有效的GMT时间,即格林威治标准时间字符串,比如Thu, 29 May 2020 06:33:03 GMT,表示格林威治时间的2020-05-29 06:33:03,即北京时间的2020-05-29 14:33:03。当客户端的时间达到这个时间点后,该cookie就会过期。

  • max-age:设置cookie的相对有效期。expire和max-age通常仅设置一个即可。比如设置max-age1000

    ,浏览器在添加cookie时,会自动设置它的expire为当前时间加上1000,作为过期时间。

    • 如果不设置expire,又没有设置max-age,则表示会话结束后过期。
    • 对于大部分浏览器而言,关闭所有浏览器窗口意味着会话结束。
  • secure:设置cookie是否是安全连接。如果设置了该值,则表示该cookie后续只能随着https请求发送。如果不设置,则表示该cookie会随着所有请求发送。

  • httponly:设置cookie是否仅能用于传输。如果设置了该值,表示该cookie仅能用于传输,而不允许在客户端通过JS获取,这对防止跨站脚本攻击(XSS)会很有用。

express中,除了可以手动设置响应头的cookie外,还可以使用一个express中间件cookie-parser

var express = require('express')
var cookieParser = require('cookie-parser')

var app = express()
// 该中间件将会更改 req 和 res 对象中跟cookie相关的方法和属性
app.use(cookieParser("abc"))

app.get("/test", function(req, res){
  // 在响应头中设置cookie
  res.cookie('键', '值', { // cookie的其他信息
    domain: "域",
    path: "路径", // 默认值为 /
    expires: 过期时间, // Date类型
    maxAge: 相对过期时间, // 单位毫秒,在响应头中会自动转换为秒
    httpOnly: true, // 是否启用 httpOnly
    signed: true, //  启用后,会使用之前配置的私钥,对值进行加密
  })
})

发送cookie

浏览器发出请求时,会自动判断是否有满足条件的cookie,如果有,则会将其附带到请求头中

具体的格式如下:

cookie: a=1; b=2; c=3

如果一个cookie同时满足以下条件,则这个cookie会被附带到请求中

  • cookie没有过期
  • cookie中的域和这次请求的域是匹配的
    • 比如cookie中的域是ke.qq.com,则可以匹配的请求域是duyi.ke.qq.comke.qq.com等等
    • 比如cookie中的域是duyi.ke.qq.com,则不能匹配ke.qq.com这样的请求域
    • cookie是不在乎端口的,只要域匹配即可
  • cookie中的path和这次请求的path是匹配的
    • 比如cookie中的path是/news,则可以匹配的请求路径可以是/news/news/detail/news/a/b/c等等,但不能匹配/blogs
    • 如果cookie的path是/,可以想象,能够匹配所有的路径
  • 验证cookie的安全传输
    • 如果cookie的secure属性是true,则请求协议必须是https,否则不会发送该cookie
    • 如果cookie的secure属性是false,则请求协议可以是http,也可以是https

服务器获取cookie

express可以通过请求头获取cookie

也可以使用下面的代码更加友好的获取cookie

req.cookies // 得到解析cookie后的一个对象
req.signedCookies // 得到对加密cookie解密之后的一个对象,解密时使用之前配置的秘钥

在浏览器端操作cookie

document.cookie // 获取所有的cookie
document.cookie = "cookie设置字符串,和响应头中的设置格式一致" // 设置某个cookie

你可能感兴趣的:(了解 node cookie 状态保持)