Express + Passport + Session。为每个页面加载执行查询

时间:2014-07-28 06:40:41

标签: node.js express passport.js

我使用Express 4.2.0和护照0.2.0。

我使用的快速会话中间件是1.2.1

我对节点认证比较陌生,所以请耐心等待。

我注意到,对于每个页面加载,passport都在执行db请求:

Executing (default): SELECT * FROM "users" WHERE "users"."user_id"=7 LIMIT 1;

这对我来说没有意义,因为我认为用户已经过身份验证和序列化。会话现在存储在浏览器cookie中。我还检查过我的浏览器中存有cookie会话。

以下是我的app.js配置:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//var sys = require('sys');
var cons = require('consolidate');

/* sequelize */
var db = require('./models'); 

/* passport and its friends */
var passport = require('passport');
var flash = require('connect-flash');
var session = require('express-session');

/* routes */
var routes = require('./routes/index');
var users = require('./routes/users');


//filesystem middleware
//var fs = require('fs');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('dust', cons.dust);
app.set('view engine', 'dust');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser('hashionhashion'));
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({ secret: 'hashionhashion' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session

//routing
app.use('/', routes);
app.use('/users', users);

这是护照序列化/反序列化函数:

passport.serializeUser(function(user, done) {
    done(null, user.user_id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    db.User.find({ where: {user_id: id} }).success(function(user){
        done(null, user);
      }).error(function(err){
        done(err, null);
      });
});

1 个答案:

答案 0 :(得分:0)

对每个获取经过身份验证的用户数据的请求执行查询有时不是一种好习惯(但它通常用于应用程序中)。

在我的某个应用中,我只需要id经过身份验证的用户而不是所有数据(例如passwordlast_login_dateregister_date,...)我更改了passport配置如下:

passport.serializeUser(function(user, done) {
    done(null, {id: user.id});
});

// used to deserialize the user
passport.deserializeUser(function(object, done) {
    done(null, object);  // object is: {id: user_id}
});

然后在您的控制器中,您可以从会话中获取用户ID:

router.get('/', function(req, res, next)=> {
    const userId = req.user.id;
    // now do a database query only if needed :)
});

您还可以定义自定义中间件以从db获取用户并设置为 req.user用于下一个中间件:

function fetchUser (req, res, next) {
    db.User.find({ where: {id:req.user.id} }).success(function(user){
        req.user = user;
        next();  // will trigger next middleware
    }).error(function(err){
        next(err);  // will trigger error handler
    });
}

router.get('/', fetchUser, function(req, res, next)=> {
    const user = req.user;
    // now user is a object that is fetched from db and has all properties
});

在这种方法中,只有在需要时才会执行查询以便从db中检索用户,而不是所有路由。

相关问题