美文网首页三月听我说前端小站
知识点 : session + 持久化

知识点 : session + 持久化

作者: 周旭_三月 | 来源:发表于2018-12-02 00:47 被阅读5次

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

    前言

    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

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

    👍

    相关文章

      网友评论

      本文标题:知识点 : session + 持久化

      本文链接:https://www.haomeiwen.com/subject/axercqtx.html