阻止Expressjs在请求包含授权头时创建会话? [英] Prevent Expressjs from creating a session when requests contain an authorization header?

查看:135
本文介绍了阻止Expressjs在请求包含授权头时创建会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个API,可以使用浏览器调用请求是交易的,也可以直接进行会话OR,例如。使用curl,其中请求是原子的。浏览器请求必须首先进行身份验证,然后使用快速会话(connect.sid)进行后续授权,直接API调用使用头文件:授权:SOMETOKEN必须发送对于每个请求。



我遇到的问题是,因为我使用相同的Web服务器来服务原子和事务流量,每个API调用都是不必要的快递会议。每个响应都包含一个Set-Cookie,所有这些会话都填满了我的会话存储。因此:当请求包含授权标头时,如何防止Express在内存存储区(Redis)中输入新的sess密钥?



注意。我得到一个更经典的方法是有一个单独的API服务器和一个单独的WEB服务器,但为什么不在一台机器上运行?对我来说,区别在于API提供数据,WEB服务视图,但超出它们是同一应用程序的一部分。我只是碰巧也允许用户直接访问他们的数据,不要强迫他们使用我的界面。





Express Config < h3>

  module.exports = function(app,exp,sessionStore,cookieParser,passport,flash){

app.configure(function(){
// Templates
app.set('views',ERNEST.root +'/ server / views');
app .set('view engine','jade');
app.set('view options',{doctype:'html',pretty:true});

//允许要上传的大文件(默认限制为100mb)
app.use(exp.limit('1000mb'));

//伪造放置和删除
app.use (exp.methodOverride());

//静态内容
app.use(exp.static(ERNEST.root +'/ server'));
app.use (exp.static(ERNEST.root +'/ public'));

//处理favicon
app.use(exp.favicon());

//上传
app.use(exp.bodyParser({keepExtensions:true}));

//配置cookie解析
if(cookieParser)app.use(cookieParser);
else app.use(exp.cookieParser());

//存储会话的地方
var session_options = {'secret':,并将它们放在套头上}
if(sessionStore)session_options.store = sessionStore;
app.use(exp.session(session_options));

//记住
app.use(function(req,res,next){
if(req.method =='POST'&& req.url = ='/ authenticate'){
if(req.body.rememberme ==='on'){
req.session.cookie.maxAge = 2592000000; // 30 * 24 * 60 * 60 * 1000 Rememeber'me'30天
} else {
req.session.cookie.expires = false;
}
}
next();
});

// PassportJS
如果(护照){
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
}
});

};



示例路线



  app.get('/ status / past_week',MID.ensureAuthenticated,MID.markStart,function(req,res){
WEB.getStatus('week' ,函数(err,statuses){
if(err)res.send(500,err);
else res.send(200,statuses);
});
});



授权中间件



  MID.ensureAuthenticated = function(req,res,next){
if(req.isAuthenticated())return next();
else {
isAuthorised(req,function(err,authorized){
if(err)return res.redirect('/');
else if(authorized)return next ();
else return res.redirect('/');
});
}

函数被授权(req,callback){
var authHeader = req.headers.authorization;
if(authHeader){
// has header,verify it
var unencoded = new Buffer(authHeader,'base64')toString();
var formatted = unencoded.toString()。trim();
ACCOUNT.verifyAuth(格式化,回调); // verifyAuth回调next()成功
} else回调(null,false); //否授权标题
}
};


解决方案

尝试这样:

  var sessionMiddleware = exp.session(session_options); 

app.use(function(req,res,next){
if(req.headers.authorization){
return next();
}
return sessionMiddleware(req,res,next);
});


I have an API that can be called either using a browser where requests are transactional and have a session OR directly, eg. using curl, where requests are atomic. Browser requests must first authenticate and then use an express session (connect.sid) for subsequent authorization, direct API calls use a header: Authorization: "SOMETOKEN" which has to be sent for every request.

The problem I have is, because I'm using the same web server to serve both atomic and transactional traffic, every API call is needlessly being given a session by Express. Every response includes a Set-Cookie and all these sessions are filling up my session store. Therefore: how can I prevent Express from entering a new sess key in the memory store (Redis) when a request contains an Authorization header?

Note. I get that a more classic approach would be to have a separate API server and a separate WEB server but why not run both on one machine? To me, the difference is that the API serves data and the WEB serves views but beyond that they are both part of the same application. I just happen to also allow users to access their data directly and don't force them to use my interface.

Express Config

module.exports = function(app, exp, sessionStore, cookieParser, passport, flash) {

    app.configure(function(){
        // Templates
        app.set('views', ERNEST.root + '/server/views');
        app.set('view engine', 'jade');
        app.set('view options', { doctype : 'html', pretty : true });

        // Allow large files to be uploaded (default limit is 100mb)
        app.use(exp.limit('1000mb'));

        // Faux putting and deleting
        app.use(exp.methodOverride());

        // Static content
        app.use(exp.static(ERNEST.root + '/server'));
        app.use(exp.static(ERNEST.root + '/public'));

        // Handle favicon
        app.use(exp.favicon());

        // For uploads
        app.use(exp.bodyParser({keepExtensions: true}));

        // Configure cookie parsing
        if ( cookieParser ) app.use(cookieParser);
        else app.use(exp.cookieParser());

        // Where to store the session
        var session_options = { 'secret': "and she put them on the mantlepiece" };
        if ( sessionStore ) session_options.store = sessionStore;
        app.use(exp.session( session_options ));

        // Rememberance
        app.use( function (req, res, next) {
            if ( req.method == 'POST' && req.url == '/authenticate' ) {
                if ( req.body.rememberme === 'on' ) {
                    req.session.cookie.maxAge = 2592000000; // 30*24*60*60*1000 Rememeber 'me' for 30 days
                } else {
                    req.session.cookie.expires = false;
                }
            }
            next();
        });

        // PassportJS
        if ( passport ){
            app.use(flash());
            app.use(passport.initialize());
            app.use(passport.session());
        }
    });

};

An example route

app.get('/status/past_week', MID.ensureAuthenticated, MID.markStart, function(req, res) {
    WEB.getStatus('week', function(err, statuses){
        if ( err ) res.send(500, err);
        else res.send(200, statuses);
    });
});

Authorization Middleware

MID.ensureAuthenticated = function(req, res, next) {
  if ( req.isAuthenticated() ) return next();
  else {
        isAuthorised(req, function(err, authorised){
            if ( err ) return res.redirect('/');
            else if ( authorised ) return next();
            else return res.redirect('/');
        });
    }

    function isAuthorised(req, callback){
        var authHeader = req.headers.authorization;
        if ( authHeader ) {
            // Has header, verify it
            var unencoded = new Buffer(authHeader, 'base64').toString();
            var formatted = unencoded.toString().trim();
            ACCOUNT.verifyAuth(formatted, callback); // verifyAuth callbacks next() when successful
        } else callback(null, false); // No Authorised header
    }
};

解决方案

Try this:

var sessionMiddleware = exp.session( session_options );

app.use(function(req, res, next) {
  if (req.headers.authorization) {
    return next();
  }
  return sessionMiddleware(req, res, next);
});

这篇关于阻止Expressjs在请求包含授权头时创建会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆