防止Expressjs在请求包含授权头时创build会话?

我有一个API,可以调用使用浏览器的请求是事务性的,并有一个会议或直接,例如。 使用curl,其中请求是primefaces的。 浏览器请求必须首先进行身份validation,然后使用快速会话(connect.sid)进行后续授权,直接API调用使用头: Authorization: "SOMETOKEN"必须为每个请求发送Authorization: "SOMETOKEN"

我遇到的问题是,因为我使用相同的Web服务器来提供primefaces和事务性stream量,所以每个API调用都会被Express无谓地授予一个会话。 每个响应都包含一个Set-Cookie,所有这些会话都填满了我的会话存储。 因此: 当请求包含授权标头时,如何防止Express在内存存储(Redis)中input新的sess密钥?

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

快速configuration

 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()); } }); }; 

一个示例路线

 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); }); }); 

授权中间件

 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 } }; 

尝试这个:

 var sessionMiddleware = exp.session( session_options ); app.use(function(req, res, next) { if (req.headers.authorization) { return next(); } return sessionMiddleware(req, res, next); }); 

看起来你需要编写自己的会话中间件。 这是一个例子 。 如果您可以创build一个单独的子域名,例如www.example.com用于浏览器会话,而app.example.com用于直接访问它,那么您应该几乎可以正确使用链接的方法,而不要启动会话为app.example.com请求。 这可能是最直接的方法,通过这个方法来表明它打算validation的方法,任何从这个方法转移都是错误的。

否则,您将不得不在中间件中检测到身份validation令牌,并且在find该令牌时不会启动会话。

减less会话存储中存储的会话数量的另一种方法是将默认maxAge设置为低。 然后,当你真的需要存储更长的会话,比如用户login后,你可以设置req.session.cookie.expires = null; 。 当用户注销时,也不要忘记将会话过期设置为低。

这是一个例子:

 // set default to something low app.use(session({ resave: true, saveUninitialized: true, cookie: { maxAge: 5 * 60 * 1000 // 5 minutes }, secret: secrets.sessionSecret, store: new MongoStore({ url: yourUrl, auto_reconnect: true }) })); // on successful login, // set expiration to null or something longer than default var time = 14 * 24 * 3600000; //2 weeks req.session.cookie.maxAge = time; req.session.cookie.expires = new Date(Date.now() + time); req.session.touch(); // on logout, reset expiration to something low var time = 5 * 60 * 1000; // 5 minutes req.session.cookie.maxAge = time; //2 weeks req.session.cookie.expires = new Date(Date.now() + time); req.session.touch(); 

当远程监控您的应用程序时,这是非常有用的,因为如果监控频率足够高,会话将会很快完成。

你总是可以捕获响应标头事件并删除'set-cookie'标头:

 app.use(function(req, res, next) { res.on('header', function () { if (req.headers.authorization) { delete res._headers['set-cookie']; } }); next(); }); 

你可以从技术上把它放在中间件链的任何地方。