本文介绍了ExpressJs Passportjs针对对路由的每个请求反序列化用户对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ExpressJS应用程序,该应用程序正在使用Passportjs与Facebook进行身份验证,并且一切正常,一个问题的例外情况.

I have a ExpressJS app that is using Passportjs to authenticate with Facebook and everything is working as expected exception for one issue.

我在/routes/下有vehicle.js,其中包含一些需要身份验证的路由(router.gets和router.posts),而有些则不需要.如果用户已登录,则vehicle.js处理的每个请求都会导致用户反序列化,这是Mongoose查找. 当请求不需要身份验证的router.get和/或router.post时,如何避免这些不必要的Mongoose查找?

I have vehicle.js under /routes/ which contains some routes (router.gets and router.posts) that need authentication and some that don't. If user is logged in then every request handled by vehicle.js causes User de-serialization which is a Mongoose lookup. How can I avoid these unnecessary Mongoose lookups when request is made to a router.get and/or router.post that do not need authentication?

我已经查看了此 SO问题,它不能解决我的问题(我在护照上方声明了静态资源,因此未通过身份验证).

I have already looked up this SO question and it does not address my problem (I have declared static resources above passport, so they are not authenticated).

Passport配置如下所示:

// Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');

app.use(expressSession({secret: 'thisIsSecret'}));
app.use(passport.initialize());
app.use(passport.session());

// Using the flash middleware provided by connect-flash to store messages in session
// and displaying in templates
var flash = require('connect-flash');
app.use(flash());

// Initialize Passport
var initPassport = require('./passport/init');
initPassport(passport);

//passing passport object could be the reason why all requested that are
//mapped in vehicle cause user de-serialization. Not sure if there is any
//alternative approach than following line that passes passport??
var vehicle = require('./routes/vehicle')(passport);

下面的isAuthenticated在vehicle.js

The following isAuthenticated is in vehicle.js

var isAuthenticated = function (req, res, next) {
  if (req.isAuthenticated())
    return next();
    // if the user is not authenticated then redirect him to the login page
    res.redirect('/vehicle/api/login');
}

之后是处理logging inlogging out的一系列routes以及对vehicle的一些操作.

Followed by a series of routes that handle logging in, logging out, as well as some actions on vehicle.

module.exports = function(passport) {
  router.get('/api/login', function(req, res) {
    res.render('vehicle/login', { message: req.flash('message') });
  });
  router.post('/api/login', passport.authenticate('login', {
    successRedirect: '/vehicle/api/list/mine',
    failureRedirect: '/vehicle/api/list',
    failureFlash : true
  }));
  ...
  ...
  ...
  router.post('/api/upload', isAuthenticated, function(req, res) {
    //this route needs to  be authenticated, so it works fine,
    //deserialization done, mongoose lookup, no problem
  });
  router.get('/api/image/:vehicleId/:filename', function(req,res) {
    //this route does not need authentication, but causes User
    //de-serialization and Mongoose lookup
  });
 return router;
}

是否由于以下行而导致对vehicle.js的每个请求都会在用户登录时导致用户反序列化?

Is it because of the following line that every request to vehicle.js causes User de-serialization when a user is logged in?

var vehicle = require('./routes/vehicle')(passport);

避免这种不必要的反序列化的一种方法是将不需要身份验证的路由从vehicle.js分离到另一个文件,并且不要将该通行证对象传递到该文件(因为它被传递给了vehicle.js app.js).我不知道这是否是解决此问题的正确方法.

One way to avoid such unnecessary de-serialization would be to separate routes that do not need authentication from vehicle.js to a different file and do not pass that passport object to that file (as it is passed to vehicle.js in app.js). I don't know if that is the correct way to resolve this issue.

推荐答案

您可以将护照中间件包装在仅针对指定路线调用该中间件的自定义中间件中.因此,代替:

You can wrap the passport middleware inside a custom middleware that only invokes it for your specified routes. So Instead of:

app.use(passport.session());

您可以:

app.use(function(req, res, next){
  if(req.url.match('api/image'))
    next(); // do not invoke passport
  else
    passport.session()(req, res, next)
    // same as doing == app.use(passport.session())
});

这篇关于ExpressJs Passportjs针对对路由的每个请求反序列化用户对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 09:05