简单的特点总结:
- cookie :在浏览器保存一些数据,每次请求向后台发送
特点:不安全、空间小(4k) - session:不是独立存在的,是基于cookie实现的,保存在服务器
cookie中会有一个session的ID,服务器利用sessionid找到session文件、读取、写入
特点:安全、空间无限
隐患:session劫持
session劫持:session_id放在cookie里面,所以是可以被看见的,也是可以被改变的。如果b拿到了a的session_id,b再用其登陆网站,那么就是以a的身份在访问这个网站了。
解决:定期更换session_id;提高cookie安全性。
提高cookie安全性的方法:
cookie校验:
req.secret='自定义的加密字符串'; //签名的密钥
res.cookie=('user','xiaoming',{signed:true}); //签名
加密后的cookie的value表面上变成了复杂的字符串,但其实还是可以通过解析被看见的,它之所以可以在一定程度上提高安全性,是因为如果cookie被别人修改了,我们可以立马发现并做出相应的操作。
机制:cookie的签名属性signed,保存我们设置的cookie,与网页发送来的cookie作比较,如果相同,表示是我们自己的cookie,否则就是别人篡改过的。
小tips:
①解析加密后的cookie
通过decodeURIComponent(‘控制台cookies里的value’),这样解析出来是一个字符串s:xiaoming.签名。
s表示signed:true。
加密后的字符串比较安全,因为它的原字符串本身就是在后台的,不像前端易被获取。
②并不是所有cookie都需要加密
因为cookie加密后的字符串很长,而cookie本身只能存储4字节,空间非常宝贵,所以我们只将重要的信息进行cookie加密。
加密和无加密的cookie在后台打印时分开打印:
console.log('签名cookie:',req.signedCookies);
console.log('无签名cookie:',req.cookies);
对cookie的操作:
a.发送cookie
res.secret='字符串';
res.cookie(名字,值,{path:'/',maxAge:毫秒,signed:true});
b.读取
解析cookie的工具:cookie-parser
server.use(cookieParser('密钥'));//给定cookie的解析规则
server.use(function(){
req.cookies; //未签名版
req.signedCookies; //签名版
});
c.删除cookie
res.clearCookie(名字);
整合cookie发送及读取:
const express=require('express'); //引入框架
const cookieParser=require('cookie-parser'); //引入解析模块
var server=express(); //创建服务器
server.use(cookieParser('字符串')); //给定cookie的解析规则 ①
server.use('/',function(req,res){
req.secret='字符串'; //cookie加密
res.cookie('user','blue',{signed:true}); //发送cookie ②
console.log(req.signedCookies); //发送签名cookie
console.log(req.cookies); //发送无签名cookie
res.send('ok');
});
server.listen(8080);
解析:
① 如果形式时server.use(cookieParser()),则只能解析无签名的cookie。
如果形式时server.use(cookieParser(‘字符串’)),则无签名的和签名的均能解析。
当首次访问的时候,第一次解析cookie,是没有的,这时第一次打印出来的cookie为undefined。
② 而首次访问时会发送一个cookie,这就保证了在下一次①步骤的解析时,会解析出相应的cookie,也会打印出相应的cookie。
关于session:
session是必须加入签名的,如果没加签名的话,系统会报错,告诉你Error:.keys required,也就是需要提供一个密钥(keys),这说明了session的安全性是比较高的。
session的主要参数:name,keys,maxAge 。
- name:name的值无具体要求,自定义即可。
- keys:keys不加给req,也不加给res,它加给sever,加给全局一个安全密钥,这样整个服务器都可以使用。形式是数组,这样使各个密钥循环使用,而且数组的长度越大,密钥的安全性越高,破解者无法知道密钥的个数、从哪个密钥开始循环、现在循环到了哪个密钥,破解也就无从谈起了。
一个例子:
var arr[];
for(var i=0;i<100000;i++){
arr.push();
}
通过随机数来设置加密数组keys,且设置0到100000的循环来循环数组里的数,这样的安全性是很高的。
- maxAge :session的有效期
maxAge越长,在用户无操作的很长的时间后保留session,对于用户更方便,不会轻易出现session已过期和需要重新登陆的情况。
但是同时也给了攻击者更长的时间来获取session,所以安全性更低。
maxAge越短,在用户无操作的很短的时间后销毁session,对于用户可能在无操作的一段时间内就需要重新登陆,从用户体验上来说可能有些繁琐。
但安全性更高,这样在无操作的一段时间后,session不存在了,破解者找不到session了,也无法进行破解等操作了。
对session的操作:
a.设置session密钥
server.use(cookieSession({
keys:[a,b,c,d]; //自定义的
}));
b.读取
解析session的中间键:cookie-session
server.use('/',function(){
req.session; //session是服务器所接收的,所以是req
});
c.删除session
delete req.session
整合session:
server.use(cookieParser()); //因为session不是独立存在的,是基于cookie的,所以仍然需要解析cookie的工具
server.use(cookieSession({
name:'sess';
keys:['a','b','c'],
maxAge:20*3600*1000; //以毫秒为单位
}));
server.use('/',function(){
……你所需要实现的内容
console.log(req.session['你所需要打印的内容']);
res.send('ok');
});
server.listen(8080);