yoho-session.js 2.38 KB
const config = global.yoho.config;
const session = require('yoho-express-session');
const _ = require('lodash');
const uuid = require('uuid');

const cookieSession = require('client-sessions');
const connectRedis = require('connect-redis');
const RedisStore = connectRedis(session);
const monitor = global.yoho.monitorSender;
const monitorType = _.get(monitor, 'type.REDIS');

/**
 * 该中间件主要把 express-session 和 client-session 集中起来处理,如果 redis 出错了,使用 cookie session
 * @param opts.backSession cookieSession 的键名
 * @returns {function(*=, *=, *)}
 */
function yohoSession(opts) {
  return (req, res, next) => {
    let notUseRedis = _.get(req.app.locals.wap, 'session.removeMemcached', false);

    opts.backSession = opts.backSession || 'session2';

    if (req.session && !notUseRedis) {
      req.sessionError = false;
    } else {
      // 重建 session
      res.emit('sessionError');
      req.sessionError = true;

      req.session = new session.Session(req, req[opts.backSession].sessionBack);
      req.session.cookie = new session.Cookie({
        domain: 'yohobuy.com',
        httpOnly: true
      });
    }

    Object.defineProperty(req.session, 'reset', {
      configurable: true,
      enumerable: false,
      value: function() {
        req.session.destroy();
        req[opts.backSession].reset();
      },
      writable: false
    });

    // 备份数据
    req[opts.backSession].sessionBack = req.session;

    next();
  };
}

module.exports = (app) => {
  app.use(session({  // eslint-disable-line
    proxy: true,
    resave: false,
    saveUninitialized: true,
    unset: 'destroy',
    secret: '82dd7e724f2c6870472c89dfa43cf48d',
    name: 'yohobuy_session',
    genid() {
      return uuid.v4();
    },
    cookie: {
      domain: 'yohobuy.com',
      httpOnly: true,
      maxAge: 1000 * 60 * 60 * 24 * 7 // 7天
    },
    store: new RedisStore(Object.assign(config.redis.session, {
      logErrors: (e) => {
        // 上报redis session错误
        monitor && monitor.tallyFail(monitorType, e);
      }
    }))
  }));

  app.use(cookieSession({ // eslint-disable-line
    requestKey: 'session2',
    cookieName: 'yohobuy_session_cookie',
    secret: '82dd7e724f2c6870472c89dfa43cf48d',
    cookie: {
      domain: 'yohobuy.com',
      ephemeral: true,
      httpOnly: true
    }
  }));

  app.use(yohoSession({
    backSession: 'session2'
  }));
};