• nodejs + express + express-session + redis


    nodejs + express + express-session + redis

    标题似乎又是不太对,大家领会精神哈

    Express

    安装express-generator,然后用它来创建一个工程;

    npm install express-generator -g
    express myApp
    cd myApp
    npm install
    npm start 或是 node bin/www

    访问 http://localhost:3000/ 即可看到Express的字样;

    Express Generator搭建HTTPS前端框架 - 简书

    Session

    在 express中操作 session要用到 express-session这个模块,主要的方法就是 session(options),
    其中 options为JSON对象,包含可选参数,主要有:

    name: 设置 cookie 中,保存 session 的字段名称,默认为 connect.sid 。
    store: session 的存储方式,默认存放在内存中,也可以使用 redis,mongodb 等。express 生态中都有相应模块的支持。
    secret: 通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改。
    cookie: 设置存放 session id 的 cookie 的相关选项,默认为(default: { path: '/', httpOnly: true, secure: false, maxAge: null })
    genid: 产生一个新的 session_id 时,所使用的函数, 默认使用 uid2 这个 npm 包。
    rolling: 每个请求都重新设置一个 cookie,默认为 false。
    resave: 即使 session 没有被修改,也保存 session 值,默认为 true。

    在原有项目中添加代码

    app.js

    var createError = require('http-errors');
    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var logger = require('morgan');
    
    var session = require('express-session');
    
    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', 'jade');
    
    app.use(logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use(session({
      secret: 'recommand 128 bytes random string', // 建议使用 128 个字符的随机字符串
      cookie: { maxAge: 60 * 1000 }
    }));
    
    app.use('/', indexRouter);
    app.use('/users', usersRouter);
    
    // 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;

    session需要在 route之前 use;

    routes/users.js

    var express = require('express');
    var router = express.Router();
    
    /* GET users listing. */
    router.get('/', function(req, res, next) {
      if(req.session.isVisit) {
        req.session.isVisit++;
        res.send('<p>第 ' + req.session.isVisit + ' 次来此页面</p>');
      } else {
        req.session.isVisit = 1;
        res.send("<p>欢迎第 1 次来此页面</p>");
      }
    });
    
    module.exports = router;

    Session中添加了 isVisit字段。

    cookie 和 session - Node.js 实战心得 - 极客学院Wiki

    Redis

    session 存放在内存中不方便进程间共享,因此可以使用 redis 等缓存来存储 session。

    使用 redis 作为缓存,可以使用 connect-redis 模块来得到 redis 连接实例,然后在 session 中设置存储方式为该实例。

    刚才的app.js

    var createError = require('http-errors');
    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var logger = require('morgan');
    
    var session = require('express-session');
    var redisStore = require('connect-redis')(session);
    
    const redis = require('redis');
    const client = redis.createClient(6379, 'IP', {auth_pass: 'password'});
    
    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());
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use(session({
      store: new redisStore({
        client: client,
        prefix: 'session:'
      }),
      secret: 'recommand 128 bytes random string'
    }));
    
    app.use('/', indexRouter);
    app.use('/users', usersRouter);
    
    // 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;

    Session -> redisStore -> client,依次依赖

    redis - npm

    connect-redis - npm

    nodejs+express+express-session+redis 实现登陆验证 - 风中追风 - SegmentFault 思否

    这些都是扯淡,用的时候一点儿也不好用,对于前后端分离造成的跨域问题简直是束手无策;

    最后都改成了用token,就像这样:

    方案一:使用token
    1.前端把account和password,提交到服务端的登录api

    2.服务端验证正确后,生成一个token,并把token和userId,存在缓存里(推荐redis数据库),然后把token返回给前端。

    3.前端每次的请求头中带token,这样就能够轻松的实现

    方案二:使用cookie

    1.client发送username和password到server

    2.server验证成功后, 写cookie到client,然后返回ok的json, 其中cookie的key要存储在redis中,value就是用户信息, 并且要设置key的超时时间,如:60分钟

    3.client收到ok后, 进行相应的业务操作, 以后每次请求server都会自动带上cookie, 不用你写代码

    4.server端的filter(你肯定用filter来实现)中会每次验证传过来的cookie的key在redis中是否存在, 有就代表登录成功过可以操作, 没有就返回错误标识注意: 在登录成功后, 每次调用服务器接口时候, 都要为redis的key进行续期,如60分钟

    5.当redis的key超过60分钟, 自己会删除这个key, 那么再次请求server时, 就会收到需要登录的返回值

    6.当用户主动退出系统的时候, 也要在server中删除redis的key

    前后端分离的项目,如何解决登录问题 - 刘元涛的个人页面 - 开源中国

  • 相关阅读:
    uva2965
    uva10755
    uva3695
    uva2678
    uva 11549
    stringstream使用笔记
    noip2016游记
    java学习(四)--- String 、StringBuffer、StringBuilder 和 数组
    java学习(三)--- 修饰符
    java学习(二)--- 变量类型
  • 原文地址:https://www.cnblogs.com/duasonir/p/9367613.html
Copyright © 2020-2023  润新知