Web安全策略之Secure Cookie
背景
提到cookie想必大家都不陌生吧,用来维护http对话身份的一个属性。提到了身份那就一定涉及到安全问题,如果别人拿到了cookie呢。在web应用中传输主流就是http协议,但是http又是不安全的,所以我们需要给cookie颁发一个属性那就是Secure属性,这样的cookie只能在https协议中传递。
http协议中的cookie
在裸奔的http协议传输过程中cookie是暴漏的,从中间拦截是可以看到cookie的。
https协议中的cookie
如果颁发了了ssl协议,在ssl下传输,cookie则不会暴漏出来。
Secure属性的使用
Secure三种设置方式
- true 只能通过https传递,如果是http场景则cookie不能被设置成功
- false 关闭该属性
- 'auto' 通过请求响应自动设置对应的值,当http与https共存的时候(https系统一般不允许http协议传递,但是http系统是可以允许https协议)一旦设置成true(Secure)后续http将丢失cookie
nodejs生成cookie配置(express)
import session from 'express-session';
app.use(
session({
name: `${process.env.SESSION_NAME}`,
secret: `${process.env.SERVER_SESSION_SECRETKEY}`,
client: sessionRedisClient,
}),
saveUninitialized: false,
resave: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000,
sameSite: 'lax',
},
})
);
app.listen(process.env.PORT || 3000, () => {
console.log('http server');
});
如果在http协议中设置secure属性会有什么效果呢
cookie: {
maxAge: 24 * 60 * 60 * 1000,
sameSite: 'lax',
secure: true, // 新增配置
},
我们会发现session id没有生成,结局就是登陆失败。且其他属性均提示⚠️(如下图)
结论如果设置了secure属性,cookie将不会传输。

我们为了验证secure的有效性,我们可以将node server变成https服务器
var server = https.createServer(
{
key: fs.readFileSync(path.join(__dirname, '../../server.key')),
cert: fs.readFileSync(path.join(__dirname, '../../server.crt')),
},
app
);
server.listen(process.env.PORT || 3000, () => {
console.log('https server');
});

响应头颁发cookie成功了,且有session id(skey).到这里就结束了吗?并没有,因为实际生产环境与本地环境并不一样,所以不妨模拟一下生产环境。
线上环境https,由于线上环境node server还是http协议,所以我们要把node server改成http协议传输,通过Nginx反向代理的形式来访问我们的server。
结构
client => reverse proxy(nginx) => server
Nginx配置
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# HTTPS server
#
server {
listen 9527 ssl;
server_name 192.168.31.43;
ssl_certificate /Users/deqi.han/frontend_project/Auto_Test/server.crt;
ssl_certificate_key /Users/deqi.han/frontend_project/Auto_Test/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /Users/deqi.han/frontend_project/Auto_Test/build/;
index index.html;
}
location /infpf/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:3000;
}
}
}
再次登陆

我们会发现session id(skey)又丢了!!!没错登陆又失败了,这是为什么?
我们打印一下请求信息

会发现进来的请求是http请求,且ip是node server的ip。没错这里就是原因,当我们设置了secure属性之后,先不说ip来源出问题http协议就是没办法传输的!!!如何解决?
设置代理信任
app.set('trust proxy', 1);
再次登陆

一切又正常了~打印信息

我们会发现请求协议变成了https,ip也是客户端ip了~,cookie又能传输了。
最终配置文件
import session from 'express-session';
app.set('trust proxy', 1);
app.use(
session({
name: `${process.env.SESSION_NAME}`,
secret: `${process.env.SERVER_SESSION_SECRETKEY}`,
client: sessionRedisClient,
}),
saveUninitialized: false,
resave: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000,
sameSite: 'lax',
},
})
);
讲到这里我想小伙伴应该了解了该属性如何使用了吧~
Web安全策略之Secure Cookie更多相关文章
JavaScript CSS Vue3 实现一个简单的Loading
配置和使用nvm免安装版本(nvm-noinstall.zip)
HarmonyOS:使用Node-API实现ArkTS与C/C++跨语言交互
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (一):项目简介及安装依赖
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (五):POST上传文件的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (八):API说明(暂时完结,后续考虑将在线版mongoDB变为本地版)
报error:0308010C:digital envelope routines::unsupported错--nodejs版本过高(nvm安装(更换)不同版本nodejs)
小结---安装nvm解决node版本不兼容的问题(node版本切换)