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

标签 node.js express passport.js

我使用的是 Express 4.2.0 和 passport 0.2.0。

我用的express-session中间件是1.2.1

我对 Node 身份验证比较陌生,所以请多多包涵。

我注意到对于每个页面加载,passport 正在执行一个数据库请求:

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

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

这是我的 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 序列化/反序列化函数:

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

最佳答案

有时对每个请求执行查询以获取经过身份验证的用户数据并不是一个好的做法(但它通常在应用程序中使用)。

在我的一个应用程序中,我只需要经过身份验证的用户的 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}
});

然后在您的 Controller 中,您可以从 session 中获取用户 ID:

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

您还可以定义一个自定义中间件来从数据库中获取用户并设置为 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
});

在这种方法中,您将执行查询以仅在需要时从数据库中检索用户,而不是针对所有路由。

关于node.js - Express + Passport + Session。为每个页面加载执行查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24989705/

相关文章:

node.js - Node 未定义

node.js - 如何运行包括 Node.js 服务器的多个 shell 命令? Ubuntu

node.js - 重新启动服务器时 Express 4 session 不持久

node.js - 如何在 Express 应用程序中的任何位置重用相同的 Sequelize 连接?

exception - Nodejs 和 Express 中 Passport 的额外验证和异常(exception)

node.js - 使用 Sails.js 和 NodeBB 的 Greenfields 项目 - Passport 是否适合提供单点登录?

javascript - 如何将 javascript 文件转换为 .exe 文件

javascript - 使用 POST 的 NodeJS 快速身份验证返回错误 发送后无法设置 header

javascript - 如何在不使用 express 的情况下为 node.js 和 socket.io 中的 Web 工具创建基本身份验证、登录系统

javascript - 错误: Corrupted zip : can't find end of central directory - XLSX