Express + Pasaporte + Sesión. Ejecuta una consulta para cada carga de página.

Estoy usando Express 4.2.0 con pasaporte 0.2.0.

El middleware de sesión rápida que estoy usando es 1.2.1

Soy relativamente nuevo en la autenticación de nodos, así que tenga paciencia conmigo.

Noté que para todos los usuarios que cargan páginas, el pasaporte está ejecutando una solicitud de db:

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

Esto no tiene sentido para mí, ya que creo que el usuario ya ha sido autenticado y serializado. Y la sesión ahora está almacenada en la cookie del navegador. También verifiqué que tengo una sesión de cookies almacenada en mi navegador.

Aquí está mi configuración de 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); 

y aquí está el pasaporte serializar / deserializar la función:

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

La ejecución de una consulta en cada solicitud para obtener los datos del usuario autenticado a veces no es una buena práctica (pero se usa comúnmente en aplicaciones).

En una de mis aplicaciones, solo necesitaba la id del usuario autenticado en lugar de todos los datos (como password , last_login_date , register_date , …) así que cambié las configuraciones de passport como a continuación:

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

y luego en sus controladores puede obtener el ID de usuario de la sesión:

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

también puede definir un middleware personalizado para obtener el usuario de la base de datos y establecerlo en req.user para usarlo en el siguiente middleware:

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

En este enfoque, ejecutará la consulta para recuperar usuarios de db solo si es necesario y no para todas las rutas.