auth.js 3.61 KB
/**
 * 认证中间件
 * @author h1bomb
 */


var _= require('lodash');
var ipaddr = require('ipaddr.js');
var options=require('../staticConfig.js').staticDir;

/**
 * 不需要权限校验配置
 */
var guestAccessList = {
    "POST:/login":true,
    "GET:/logout":true
}

var NO_AUTH = '没有权限!';

var WEBSITE = 2;

var CSS_FILE = '/dist/login.css';

var STATIC_PATH = '';

var env = process.env.NODE_ENV || 'development';

//设置对于环境环境
if(env!=='development') {
    CSS_FILE = options[env].path+'/login.css';
    STATIC_PATH = options[env].path;
}


/**
 * 认证中间件
 * @param  {Object} req  请求对象
 * @param  {Object} res  响应对象
 * @param  {Function} next 执行下个中间件
 * @return {void}       无返回
 */
module.exports = function(req, res, next) {

    //方法名称
    var method = req.method;

    
    //访问路由路径
    var path = req.route?req.route.path:'';
    if(req.session.user&&!checkPath(req.path,req)) {
        res.status(403);
        res.render('error/error_nolayout',{message:NO_AUTH,layout:false,cssfile:CSS_FILE});
        return;
    }
    //进行白名单验证和session验证
    if(guestAccessList[method+":"+path]||req.session.user) {
        //判断是否已存在appendData
        if(!res.appendData) {
            res.appendData = _.cloneDeep(req.session.user);
        } else {
            res.appendData = _.merge({},res.appendData,req.session.user);
        }

        //添加当前菜单激活
        addActiveMenu(req,res);
        
        //添加管理员信息到http头
        if(req.session.user) {
            appendAdminInfo(req,req.session.user.auth);
        }
        
        next();
    } else {
        req.app.logger.log('info',"CurentView:Login");
        //如果是登陆界面不加载布局
        res.render('pages/login',{layout:false,cssfile:CSS_FILE,path:STATIC_PATH});
    }
}

/**
 * 添加当前激活的菜单
 * @param {Object} req 请求对象
 * @param {Object} res 返回对象
 */
function addActiveMenu(req,res) {
    var curUrl = req.originalUrl;
    var lastOpen = req.headers['referer'];
    var hasActive = false;
    if(!res.appendData||!res.appendData.menu) {
        return;
    }
    var menu = _.cloneDeep(res.appendData.menu);
    
    function loop(list,condition) {
        _.forEach(menu,function(v,k) {
            _.forEach(v.menu,function(val,key) {
                if(condition(val.href,curUrl)) {
                    v.active = 'active';
                    val.active = 'active';
                    hasActive = true;
                }
            });
        });
    }

    loop(menu,function(url) { return url === curUrl;});

    if(!hasActive && lastOpen) {
        loop(menu,function(url) { return lastOpen.indexOf(url)>-1;});
    }
    res.appendData.menu = menu;
}

/**
 * 检查路径是否没有权限
 * @param  {String} path
 * @param {Object} req
 * @return {Boolean}
 */
function checkPath(path,req) {
    var right = req.session.user.noRight;
    var ret = true;
    _.forEach(right,function(v,k){
        if(path.indexOf(k)>-1) {
            ret = false;
            return;
        }
    });
    return ret;
}

/**
 * 附加管理员的信息
 * @param  {Request} req  请求对象
 * @param  {Number} uid  用户ID
 * @param  {String} name 用户名
 * @return {Object}      用户信息对象
 */
function appendAdminInfo(req,auth) {
    var ipObject = ipaddr.process(req.ip).octets;
    var ip = ipObject?ipObject.join('.'):req.ip;
    req._yoheaders = {
        'x-user-id':auth.pid,
        'x-user-name':auth.account,
        'x-site-type':WEBSITE,
        'x-client-ip':ip,
        'x-shop-id':auth.shopId
    };
}