We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cookie存储在浏览器,在浏览器请求服务器时,其中的数据都会被发送到服务端,常用来做用户信息校验等。
但由于Cookie存储在浏览器,容易受到篡改,安全性较差。
处理Cookie,可以使用中间件cookie-parser
示例代码:/lesson05/server.js
使用cookie-parser中间件时,需要先通过server.use(cookieParser())解析cookie,之后就可以在req.cookies属性中读取到cookie的值。
server.use(cookieParser())
req.cookies
在浏览器打开http://localhost:8080/cookie,在控制台写入cookie{"userName":"lee"}。
{"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可以用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的签名即是使用一个存储在服务端的密钥对Cookie进行加密,Cookie中存储的数据是经过密钥加密的,因此客户端如果对Cookie进行修改,服务端校验就无法通过。
若需要给Cookie进行签名,首先需要给cookieParser的第一个参数传入一个字符串密钥:
// 解析Cookie server.use(cookieParser( // 签名用密钥,需要保密,仅存储在服务端 'NpLRTpy1vbBzEw2JcAxpf970kOk2RViDn5wKwrMv' ))
这样就可以开始设置签名Cookie了,只需要在res.cookie方法的配置参数中设置signed: true属性:
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。
password
s%3Atest123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
如果用decodeURIComponent方法进行解码,结果为s:test123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg。
s:test123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
其意义如下:
s
test123
HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
此时可以看到服务端打印结果为signedCookies: {"password":"test123"}。
signedCookies: {"password":"test123"}
如果用户在客户端对签名的Cookie进行了修改,例如在浏览器控制台,将password改为s%3Atest456.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg。
s%3Atest456.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
此时在服务端打印的结果为signedCookies: {"password":false},表示校验失败。
signedCookies: {"password":false}
同时浏览器中的Cookie值被重新修改为了s%3Atest123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg。
除非用户在修改签名的Cookie的值时,将该值的签名一起修改,否则校验是无法通过的。
但由于签名是由服务端的密钥计算而成,因此这个值通常是安全的。
不过,因为对Cookie进行签名,会占用更多的Cookie存储空间,而Cookie在浏览器中最多只能存储4K,所以签名不可滥用,只用来保护重要的数据即可。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
阅读更多系列文章请访问我的GitHub博客,示例代码请访问这里。
Cookie介绍
Cookie存储在浏览器,在浏览器请求服务器时,其中的数据都会被发送到服务端,常用来做用户信息校验等。
但由于Cookie存储在浏览器,容易受到篡改,安全性较差。
使用cookie-parser处理Cookie
处理Cookie,可以使用中间件cookie-parser
读取Cookie
使用cookie-parser中间件时,需要先通过
server.use(cookieParser())
解析cookie,之后就可以在req.cookies
属性中读取到cookie的值。在浏览器打开http://localhost:8080/cookie,在控制台写入cookie
{"userName":"lee"}
。在浏览器打开http://localhost:8080/cookie,服务端打印结果为:
{"userName":"lee"}
。设置Cookie
设置Cookie可以用Express自带的方法res.cookie。
方法的第一个参数为设置的属性名,第二个参数为属性值,第三个参数为配置项,例如:
在浏览器的控制台中,可以看到设置的Cookie为
{"userName":"lee"}
,有效期是14天。Cookie的签名
Cookie的签名即是使用一个存储在服务端的密钥对Cookie进行加密,Cookie中存储的数据是经过密钥加密的,因此客户端如果对Cookie进行修改,服务端校验就无法通过。
设置密钥
若需要给Cookie进行签名,首先需要给cookieParser的第一个参数传入一个字符串密钥:
签名Cookie
这样就可以开始设置签名Cookie了,只需要在
res.cookie
方法的配置参数中设置signed: true
属性:在浏览器打开http://localhost:8080/cookie,可以看到Cookie中被设置了
password
属性,其值为s%3Atest123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
。如果用decodeURIComponent方法进行解码,结果为
s:test123.HrZ44MCUeLXj0uZAzTpCXWduflOsmfBs5XsuK4eTMvg
。其意义如下:
s
表示该Cookie为签名Cookietest123
表示该Cookie设置的值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,所以签名不可滥用,只用来保护重要的数据即可。
The text was updated successfully, but these errors were encountered: