为什么要cookie、session?
http:不足之处在于无状态,两次请求间不能判断是否是同一个人。
那是否可以用ip地址判断?不能,公司的出口都是同一IP。每次刷新都要重新登陆,这时用户体验度极大降低。所以服务端要为特定的用户创建了特定的session,用用于标识这个用户,并且跟踪用户。这个session是保存在服务端的,有一个唯一标识
- cookie:在浏览器保存一些数据,每次向服务器发送请求都会带过来。用户可修改,不够安全且大小有限(4k)。
- session:在服务器端保存数据。相对安全。
既然cookie储存空间有限并且不够安全,为什么还要用?
- 因为session是基于cookie实现的。(cookie携带session-id)cookie中会有一个session的ID,服务器利用sessionid找到session文件、读取、写入等操作。
- 隐患:session劫持 (sessionid)
- 缓解方法:更换session和cookie加密
cookie
- 发送 cookie,设置有效期
会话 cookie: 保存在浏览器,关掉浏览器后被清除
持久 cookie:保存在文件中,除非用户手动清除或到期,cookie不会被清除
const express = require('express');
var server = express();
server.use('/aaa/a.html',function(req,res){//只能对aaa目录下的a.html起作用
res.cookie('user','blue',{
path:'/aaa',
maxAge:30*24*3600*1000
});//path:aaa目录下可以读取此cookie maxAge:过期时间换算为毫秒 path:表示 cookie 影响到的路径,匹配该路径才发送这个 cookie。
res.send('ok');
});
server.listen(8080);
如图:有效期为30天
- 读取——使用cookie-parser中间件
值得注意的是,第五行,use 第一个参数为'/aaa'
,则在http://localhost:8080/aaa/ccc
也能读取到此cookie,这说明 cookie是向上级读取的
。
- 我们已经了解了,在控制台可以读取到 cookie 的值,所以 cookie 不够安全。这时候我们可以对 cookie 进行签名,来加密,(ps:记得要设置参数
signed:true;
) 然后在获取的时候,告诉 req,我们需要的是签名后的 cookie。
const express = require('express');
const cookieParser = require('cookie-parser');
var app = express();
app.listen(8080);
app.use(cookieParser('这段签名的字符串可以是随意的'));
app.get('/',function (req,res) {
res.secret='这段签名的字符串可以是随意的';
res.cookie('name','GeZi',{
path:'/',//访问哪一个路径的时加上cookie
maxAge:20*60*1000,//cookie的存活时间,单位毫秒
signed:true//是否加签名
});
console.log('没有签名的cookie:',req.cookies);
console.log('签名后的cookie:',req.signedCookies);
res.send(req.cookies);
});
结果如下图:
- cookie删除
res.clearCookie('name')
关于 cookie 的补充
- res设置cookie, req识别cookie。
- Cookie是不可跨域的;在没有经过任何处理的情况下,二级域名不同也是不行的。(
wenku.baidu.com和baike.baidu.com
)。 - 浏览器的同源策略
-
URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。
- 对于 Cookie 来说,Cookie 的同源只关注域名,是忽略协议和端口的。所以一般情况下,
https://localhost:80/
和http://localhost:8080/
的 Cookie 是共享的。
-
- 数量限制:浏览器对于Cookie在数量上是有限制的,如果超过了自然会有一些剔除策略。最近最少使用(LRU)方法:在达到cookie限制时自动地剔除最老的cookie,以便腾出空间给最新的cookie。Internet Explorer和Opera使用这种方法。Firefox决定随机删除Cookie集中的一个Cookie,并没有什么章法。
session
- session主要用于三个目的:
1.会话管理 登录,购物车,游戏分数或服务器应记住的任何其他内容
2.个性化用户首选项,主题和其他设置
3.跟踪记录和分析用户行为
- session 是基于 cookie生成的,这里用到cookie-session中间件,额外给一个keys用于加密,必须在cookie-parse下面
const express = require('express');
const cookieParser = require('cookie-parser');
const cookieSeesion = require('cookie-session');
var app = express();
app.listen(8080);
app.use(cookieParser('这段签名的字符串可以是随意的'));
(function () {
var arr = [];
for(var i = 0;i<10000;i++){
arr.push('keys_'+Math.random());
}
app.use(cookieSeesion({
keys:arr,
name:'session_id',//加密的cookie的名字,最后通过这个来从服务端查找到对应的人 maxAge:20*60*1000
}))
})();
app.get('/',function (req,res) {
console.log(req.session['test']);
if(typeof req.session['test'] == 'undefined'){
req.session['test'] = 'xixi';
res.send('这是第一次访问');
}else{
res.send('这不是第一次访问');
}});