第十九天、cookie和session

一、关于Cookie

在我们关闭一个登录过的网址并重新打开它后,我们的登录信息依然没有丢失;当我们浏览了商品后历史记录里出现了我们点击过的商品;当我们推回到首页后,推荐商品也为我们选出了相似物品;事实上当我们有过此类操作后,浏览器会将我们的操作信息保存到cookie上面。阿进而言之,cookie就是储存在用户本地终端上的数据。

Cookie的特点

  • cookie保存在浏览器本地,只要不过期关闭浏览器也会存在。
  • 正常情况下cookie不加密,用户可轻松看到
  • 用户可以删除或者禁用cookie
  • cookie可以被篡改
  • cookie可用于攻击
  • cookie存储量很小,大小一般是4k
  • 发送请求自动带上登录信息

二、Cookie的安装及使用

1.安装

cnpm install cookie-parser --save

2.引入

const cookieParser=require("cookie-parser");

3.设置中间件

app.use(cookieParser());

4.设置cookie

res.cookie("name",'zhangsan',{maxAge: 900000, httpOnly: true});
//res.cookie(名称,值,{配置信息})

关于设置cookie的参数说明:

  • domain : 域名
  • name=value:键值对,可以设置要保存的 Key/Value,注意这里的 name 不能和其他属性项的名字一样
  • Expires: 过期时间(秒),在设置的某个时间点后该 Cookie 就会失效,如 expires=Wednesday, 09-Nov-99 23:12:40 GMT。
  • maxAge: 最大失效时间(毫秒),设置在多少后失效 。
  • secure: 当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效 。
  • Path: 表示 在那个路由下可以访问到cookie。
  • httpOnly:是微软对 COOKIE 做的扩展。如果在 COOKIE 中设置了“httpOnly”属性,则通过程序(JS 脚本、applet 等)将无法读取到COOKIE 信息,防止 XSS 攻击的产生 。
  • singed:表示是否签名cookie, 设为true 会对这个 cookie 签名,这样就需要用 res.signedCookies 而不是 res.cookies 访问它。被篡改的签名 cookie 会被服务器拒绝,并且 cookie 值会重置为它的原始值。

5.获取cookie

req.cookies.name;

下面是一个基础实例:

const express=require("express");
const cookieParser=require("cookie-parser");

var app=express();

//设置中间件
app.use(cookieParser());

app.get("/",function(req,res){
    res.send("首页");
});

//设置cookie
app.get("/set",function(req,res){
    res.cookie("userName",'张三',{maxAge: 20000, httpOnly: true});
    res.send("设置cookie成功");
});

//获取cookie
app.get("/get",function(req,res){
    console.log(req.cookies.userName);
    res.send("获取cookie成功,cookie为:"+ req.cookies.userName);
});

app.listen(8080);

当访问set路由后会设置cookie,当访问get路由后会获取到设置的cookie值。当然你也可以在其他页面继续获取当前cookie,以实现cookie共享。

三、多个二级域名共享cookie

只需要增加res.cookie中option对象的值,即可实现对相应路由下多个二级路由的cookie进行共享,代码如下:

const express=require("express");
const cookieParser=require("cookie-parser");

var app=express();

//设置中间件
app.use(cookieParser());

app.get("/",function(req,res){
    res.send("首页");
});

//设置cookie
app.get("/set",function(req,res){
    res.cookie("userName",'张三',{maxAge: 200000, httpOnly: true,domain: "ccc.com"});
    res.send("设置cookie成功");
});

//获取cookie
app.get("/get",function(req,res){
    console.log(req.cookies.userName);
    res.send("获取cookie成功,cookie为:"+ req.cookies.userName);
});

app.listen(8080);

可以看到

不同的二级域名也能访问到相同的cookie,只要满足ccc.com这个顶级域名就行。

四、关于cookie加密

cookie加密是让客户端用户无法的获取cookie明文信息,是数据安全的重要部分;一般的我们可以在保存cookie时对cookie信息进行加密,或者在res.cookie中对option对象的signed属性设置设置成true即可。

使用 signed 属性进行cookie加密

如下列代码:

const express = require("express");
const cookieParser = require("cookie-parser");

var app = express();
app.use(cookieParser('secret'));

app.get("/",function(req,res){
    res.send("主页");
});

//获取cookie
app.use(function(req,res,next){
    console.log(req.signedCookies.name);
    next();
});

//设置cookie
app.use(function(req,res,next){
    console.log(res.cookie("name","zhangsan",{httpOnly: true,maxAge: 200000,signed: true}));
    res.end("cookie为:"+req.signedCookies.name);
});

app.listen(8080);

签名原理

Express用于对cookie签名,而cookie-parser则是实现对签名的解析。实质是把cookie设置的值和cookieParser(‘secret’);中的secret进行hmac加密,之后和cookie值加“.”的方式拼接起来。 当option中signed设置为true后,底层会将cookie的值与“secret”进行hmac加密;

如何解析

cookie-parser中间件在解析签名cookie时做了两件事:

  • 将签名cookie对应的原始值提取出来
  • 验证签名cookie是否合法

直接对cookie值加密

node为我们提供了一个核心安全模块“crypto”,它提供了很多安全相关的功能,如摘要运算、加密、电子签名等。 这是,我们便可很轻易的封装一个加密模块:

const crypto=require('crypto');

module.exports={
    //MD5封装
    MD5_SUFFIX:'s5w84&&d4d473885s2025s5*4s2',
    md5:function(str){
        var obj=crypto.createHash('md5');
        obj.update(str);        
        return obj.digest('hex');
    }
}

之后只需要进行相应导入即可

const common=require('./MD5');

var str='123456';
var str=common.md5(str+'s5w84&&d4d473885s2025s5*4s2');
console.log(str);

设置cookie代码如下:

const express=require("express");
const cookieParser=require("cookie-parser");
var cry = require('./md5');

var app=express();

var str='hello-123';
var str=cry.md5(str+'s5w84&&d4d473885s2025s5*4s2');

//设置中间件
app.use(cookieParser());

//获取加密cookie
app.use(function(req,res,next){
    console.log(req.cookies.userName);
    next();
});

//设置并加密cookie
app.use(function(req,res,next){
    res.cookie("userName", str, {maxAge: 5*60*1000, httpOnly: true});
    res.end("set ok");
});

app.listen(8080);

如果是在判断登录时,只需将用户输入的账号进行同样加密操作在进行比较即可知道账户是否正确。 crypto所涉及的加密方式有很多,推荐大家都写模块引用,这样更方便后期的维护。

五、关于session

session是另一种记录客户状态的机制,与cookie保存在客户端浏览器不同,session保存在服务器当中; 当客户端访问服务器时,服务器会生成一个session对象,对象中保存的是key:value值,同时服务器会将key传回给客户端的cookie当中;当用户第二次访问服务器时,就会把cookie当中的key传回到服务器中,最后服务器会吧value值返回给客户端。 因此上面的key则是全局唯一的标识,客户端和服务端依靠这个全局唯一的标识来访问会话信息数据。

设置session

我们使用express-session模块来设置session

1.安装express-session
cnpm install express-session --save
2.引入express-session模块
const session=require("express-session");
3.设置session
session(options);

如下列代码:

const express=require("express");
const session=require("express-session");

var app=express();

//配置中间件
app.use(session({
    secret: "keyboard cat",
     resave: false,
     saveUninitialized: true,
     cookie: ('name', 'value',{maxAge:  5*60*1000,secure: false})
}));

app.use('/login',function(req,res){
    //设置session
    req.session.userinfo='张三';
    res.send("登陆成功!");
});

app.use('/',function(req,res){
    //获取session
    if(req.session.userinfo){
        res.send("hello "+req.session.userinfo+",welcome");
    }else{
        res.send("未登陆");
    }
});

app.listen(8080);

在session(option)中对session进行设置

session的常用方法

//设置session
req.session.username="张三"

//获取session
req.session.username

//重新设置cookie的过期时间
req.session.cookie.maxAge=1000;

//销毁session
req.session.destroy(function(err){
    
})

以下演示通过销毁session的方式来退出登录

const express=require("express");
const session=require("express-session");

var app=express();

//配置中间件
app.use(session({
    secret: "keyboard cat",
     resave: false,
     saveUninitialized: true,
     cookie: ('name', 'value',{ maxAge:  5*60*1000,
                                secure: false,
                                name: "seName",
                                resave: false})
}));

app.use('/login',function(req,res){
    //设置session
    req.session.userinfo='张三';
    res.send("登陆成功!");
});

app.use('/loginOut',function(req,res){
    //注销session
    req.session.destroy(function(err){
        res.send("退出登录!"+err);
    });
});

app.use('/',function(req,res){
    //获取session
    if(req.session.userinfo){
        res.send("hello "+req.session.userinfo+",welcome to index");
    }else{
        res.send("未登陆");
    }
});

app.listen(8080);

当我们进入到主页时,未显示任何信息,进入login路由后,自动设置session,这是回到主页则显示session信息,之后进入loginOut路由已注销session信息,再回到首页显示为登陆。

药不能停!!

日期:2021/12/9

学习参考视频:*https://www.bilibili.com/video/BV1i7411G7kW?p=52&t=10.3

学习参考文档参考部分相关视频文案和课件,仅供个人学习和记录

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容