Express教程05:Cookie

栏目: Node.js · 发布时间: 6年前

内容简介:Cookie存储在浏览器,在浏览器请求服务器时,其中的数据都会被发送到服务端,常用来做用户信息校验等。但由于Cookie存储在浏览器,容易受到篡改,安全性较差。处理Cookie,可以使用中间件

Cookie存储在浏览器,在浏览器请求服务器时,其中的数据都会被发送到服务端,常用来做用户信息校验等。

但由于Cookie存储在浏览器,容易受到篡改,安全性较差。

使用cookie-parser处理Cookie

处理Cookie,可以使用中间件 cookie-parser

读取Cookie

示例代码:/lesson05/server.js

使用cookie-parser中间件时,需要先通过 server.use(cookieParser()) 解析cookie,之后就可以在 req.cookies 属性中读取到cookie的值。

在浏览器打开 http://localhost:8080/cookie ,在控制台写入cookie {"userName":"lee"}

// 使用cookie-parser中间件,解析Cookie
server.use(cookieParser())

server.get('/cookie', (req, res, next) => {
  // 读取cookieParser解析的Cookie
  console.log(req.cookies)

  res.send(`cookies: ${JSON.stringify(req.cookies)}`)
})
复制代码

在浏览器打开 http://localhost:8080/cookie ,服务端打印结果为: {"userName":"lee"}

设置Cookie

示例代码:/lesson05/server.js

设置Cookie可以用Express自带的方法res.cookie。

方法的第一个参数为设置的属性名,第二个参数为属性值,第三个参数为配置项,例如:

server.get('/cookie', (req, res, next) => {
  // express自带的设置Cookie方法
  res.cookie('userName', 'lee', {
    // 设置该Cookie只可以由服务端访问,即前端JavaScript无法访问document.cookie获取该值,但控制台还是可以查看和修改
    httpOnly: true,
    // 只有通过HTTPS请求的Cookie才被使用,否则都认为是错误的Cookie
    // secure: true,
    // 设置保存Cookie的域名,浏览器查找Cookie时,子域名(如translate.google.com)可以访问主域名(google.com)下的Cookie,而主域名(google.com)不可以访问子域名(如translate.google.com)下的Cookie
    // 本地测试可直接设置为localhost
    domain: 'localhost',
    // 设置保存Cookie的路径,浏览器查找Cookie时,子路径(如/map)可以访问根路径('/')下设置的Cookie,而根路径('/')无法访问子路径(如/map)下设置的Cookie
    path: '/',
    // 通过expires设置Cookie过期时间为14天后
    // expires: new Date(new Date().getTime() + 14 * 86400000),
    // 通过maxAge设置Cookie过期时间为14天后
    maxAge: 14 * 86400000,
  })

  // 读取cookieParser解析的Cookie
  console.log(req.cookies)

  res.send(`cookies: ${JSON.stringify(req.cookies)}`)
})
复制代码

在浏览器的控制台中,可以看到设置的Cookie为 {"userName":"lee"} ,有效期是14天。

Cookie的签名

示例代码:/lesson05/server.js

Cookie的签名即是使用一个存储在服务端的密钥对Cookie进行加密,Cookie中存储的数据是经过密钥加密的,因此客户端如果对Cookie进行修改,服务端校验就无法通过。

设置密钥

若需要给Cookie进行签名,首先需要给cookieParser的第一个参数传入一个字符串密钥:

// 解析Cookie
server.use(cookieParser(
  // 签名用密钥,需要保密,仅存储在服务端
  'NpLRTpy1vbBzEw2JcAxpf970kOk2RViDn5wKwrMv'
))
复制代码

签名Cookie

这样就可以开始设置签名Cookie了,只需要在 res.cookie 方法的配置参数中设置 signed: true 属性:

res.cookie('password', 'test123', {
  httpOnly: true,
  domain: 'localhost',
  path: '/',
  maxAge: 14 * 86400000,
  // 开启该Cookie的签名模式
  signed: true
})
复制代码

在浏览器打开 http://localhost:8080/cookie ,可以看到Cookie中被设置了 password 属性,其值为 s%3Atest123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg

如果用decodeURIComponent方法进行解码,结果为 s:test123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg

其意义如下:

  1. s 表示该Cookie为签名Cookie
  2. test123 表示该Cookie设置的值
  3. HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg 表示对该值的签名,也就是说当服务端接收到该Cookie时,会使用服务端的密钥对 test123 进行签名,再与 HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg 进行对比,如果正确才可以使用。

此时可以看到服务端打印结果为 signedCookies: {"password":"test123"}

在客户端修改签名的Cookie

如果用户在客户端对签名的Cookie进行了修改,例如在浏览器控制台,将password改为 s%3Atest456.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg

此时在服务端打印的结果为 signedCookies: {"password":false} ,表示校验失败。

同时浏览器中的Cookie值被重新修改为了 s%3Atest123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg

除非用户在修改签名的Cookie的值时,将该值的签名一起修改,否则校验是无法通过的。

但由于签名是由服务端的密钥计算而成,因此这个值通常是安全的。

不过,因为对Cookie进行签名,会占用更多的Cookie存储空间,而Cookie在浏览器中最多只能存储4K,所以签名不可滥用,只用来保护重要的数据即可。


以上所述就是小编给大家介绍的《Express教程05:Cookie》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First Design Patterns

Head First Design Patterns

Elisabeth Freeman、Eric Freeman、Bert Bates、Kathy Sierra、Elisabeth Robson / O'Reilly Media / 2004-11-1 / USD 49.99

You're not alone. At any given moment, somewhere in the world someone struggles with the same software design problems you have. You know you don't want to reinvent the wheel (or worse, a flat tire),......一起来看看 《Head First Design Patterns》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具