知识点 : session + 持久化

前面是瞎扯,代码在后面。

前言

http 请求是无状态的,什么是无状态呢,就是你先后向服务器发送两个请求,服务器那边比较糊涂,自己是没有办法识别这两个请求是否是同一个用户发送来的。

也就是说,我上一秒给你五毛钱你下一秒就不认账的意思。

为了避免这种情况发生,我们告诉服务器,对岸的朋友来的时候,你给他一个签名,告诉他,下次带着签名过来,确认一下是不是对的人。

当然,这个签名也是有 有效期 的。

所以,我们开发者就在用户第一个请求过来的时候存起来,然后给用户一个对应的标识,这个标识也是有 有效期 的,用户下一个请求过来的时候判断一下这个标识是否对应是否符合条件,if true next else redirect ,就这样。

当然,程序员是无敌的嘛,我们有一百种改变世界的办法,如今,我已经找到了这样的办法,本篇简书就到此结束,谢谢大家!!!

调皮

session

What!!!看到这里你还问我 session 是什么?WTF

嘿siri,session 是什么东东

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。有关使用 Session 对象的详细信息,请参阅“ASP 应用程序”部分的“管理会话”。注意 会话状态仅在支持 cookie 的浏览器中保留。

嘿siri,自杀

......

简单的说,session 可以用来维持会话,服务器每天要接受 XXX 个请求,上面说了 http 是无状态的,哪能分得出谁是谁,不过 session 可以用来帮助服务器区分哪些请求对应哪些用户,对的,就这样,不知道有没有说清楚~

举个例子吧,刚学编程时会接触到登陆功能,登录成功的时候一定要存一个 session 然后返回到用户的 cookie 中,用来保持这个用户的会话信息,用户下个请求携带着 cookie 信息来的时候判断一下该用户是否登录,然后在进行后续的一顿操作,嗯,就这样 ~ 还有不懂得可以在网上找一些资料更详细的了解一下这一块 ~

基于内存来管理 session

刚开始我们为了方便快捷会把 session 存在服务器的内存中,就像下面这样:

变动的地方会用 start 和 end 标识出来

// app.js 文件中
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
// start 
// 安装 express-session 模块 并引入
var session = require('express-session'); 
// end
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

// start 
// session 的一些配置
app.use(session({
  secret: 'zz',
  cookie:{maxAge:60000},
  resave: false,
  saveUninitialized: true
}));
// end

app.use('/static',express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

// ./routes/index.js 文件中
var express = require('express');
var router = express.Router();

/* GET home page. */
// 用来为这个用户存储一个 session
router.get('/a', function(req, res, next) {
  var a = Math.floor(Math.random()*10)+''
  req.session.user = a
  res.send(a)
});

// 在页面上打印自己在 session 中存储的信息
router.get('/b', function(req, res, next) {
  req.session.touch();
  res.send(req.session.user)
});

module.exports = router;

http://localhost:3000/a
http://localhost:3000/b

上面这种基于内存来存储 session 方法唯一的好处是方便省事,适合初学,但是也存在好多缺点。比如说:

  1. 如果用户量比较大,session 会把内存占满
  2. 服务器挂了,然后重启后 session 就不存在了
  3. 项目部署在多台服务器的集群中,就不好使了
    ......

基于 mongo 来管理 session

不一定要用 mongo 来管理 session,你们可以用 redis 、 memcache 、mysql 等都可以,我这里用 mongo 是因为电脑里面刚装了个 mongo , 就顺手拿来用了。

话不多说,先上代码为敬~

// app.js 文件中, ./routes/index.js 文件不变
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
// start 
// 引入 这两个 第三方库
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
// end
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

// start
// 设置 session 存储的一些配置选项
app.use(session({
  secret: 'zz',
  cookie: {
      maxAge: 10000
  },
  resave: false,
  saveUninitialized: true,
  store: new MongoStore({
    url:'mongodb://localhost/ims',
    collection:'sessions'
  })
}))
// end

app.use('/static',express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

http://localhost:3000/a
http://localhost:3000/b
mongo 中 session 数据

上图中可以看到,mongo 中存储了一条 session 记录,这样你如果项目跑在多台服务器的话,这条 session 记录就可以在这多台服务器中共享,即使其中某台服务器挂了也不影响 session 的存储,从而来达到 session 持久化存储。

总结

基于内存的 session 存储

0.如果用户量比较大,session 会把内存占满

1.服务器挂了,然后重启后 session 就不存在了

2.项目部署在多台服务器的集群中,就不好使了

......

session 持久化存储

0.提高服务器内存的利用率

1.在多台服务器同时对外提供服务的集群系统中,可以共享 session

2.当某台服务器挂掉后,重启以后还可以使用之前未过期的 session

这么枯燥乏味的文章能看到这里已经很棒了,这些东西都太抽象了,刚开始肯定不好理解,建议多查询一些资料,亲自试验一下,感受一下成功的喜悦,嗯哼~

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

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,872评论 2 89
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,158评论 11 349
  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,136评论 0 9
  • 目录Cookie机制什么是CookieCookie的不可跨域名性Unicode编码:保存中文BASE64编码:保存...
    Tomatoro阅读 16,894评论 7 186
  • 1、简述 网络的七层协议从上到下:7、应用层 6、表示层 5、会话层 4、传输层 3、网络层 2、数据链路层 1...
    starHanJu阅读 328评论 0 2