Express + Passport +会话.对每个页面加载执行查询 [英] Express + Passport + Session. Executes a query for every page load

查看:57
本文介绍了Express + Passport +会话.对每个页面加载执行查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Express 4.2.0,护照为0.2.0.

I'm using Express 4.2.0 with passport 0.2.0.

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

The express-session middleware that I am using is 1.2.1

我对节点身份认证还比较陌生,所以请多多包涵.

I'm relatively new to node authentication so please bear with me.

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

I noticed that for everyone page load, passport is executing a db request:

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

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

This doesn't make sense to me as I would think that the user has already been authenticated and serialized. And the session is now stored in the browser cookie. I also checked that I do have a cookie session stored in my browser.

这是我的app.js配置:

Here are my app.js configuration:

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

这是护照序列化/反序列化功能:

and here is the passport serialize/deserialize function:

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

推荐答案

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

Executing a query on each request to fetch the authenticated user data sometimes is not a good practice(but it is commonly used in apps).

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

In one of my apps, i only needed id of the authenticated user rather than all data (like password,last_login_date,register_date, ...) so i changed passport configs like below:

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:

and then in your controllers you can get user id from session:

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

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

you can also define a custom middleware to fetch user from db and set to req.user to use in next 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
});

在这种方法中,您仅在需要时才执行查询以从db中检索用户,而不是对所有路由都如此.

In this approach you'll execute query for retrieving user from db only if it's needed and not for all routes.

这篇关于Express + Passport +会话.对每个页面加载执行查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆