Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 护照使用者&;反序列化用户_Node.js_Session_Authentication_Ldap_Passport.js - Fatal编程技术网

Node.js 护照使用者&;反序列化用户

Node.js 护照使用者&;反序列化用户,node.js,session,authentication,ldap,passport.js,Node.js,Session,Authentication,Ldap,Passport.js,关于这场争论,我已经读了所有的东西,但仍然不能理解。Passport Js网站上的文档非常模糊 我使用Passport JS和Passport ldapauth策略我没有数据库我显然不想在每次请求时都点击LDAP服务器。我想第一次在POST/login路由上使用LDAP的passport策略对用户进行身份验证,将用户存储在会话中,然后在每次后续请求中,我只想检查用户是否已经登录 我正在尝试使用会话,但我无法理解如何将Passport+会话与序列化/反序列化流一起使用。我检查的每个示例都在反序列化

关于这场争论,我已经读了所有的东西,但仍然不能理解。Passport Js网站上的文档非常模糊

我使用Passport JS和Passport ldapauth策略我没有数据库我显然不想在每次请求时都点击LDAP服务器。我想第一次在POST
/login
路由上使用LDAP的passport策略对用户进行身份验证,将用户存储在会话中,然后在每次后续请求中,我只想检查用户是否已经登录

我正在尝试使用会话,但我无法理解如何将Passport+会话与序列化/反序列化流一起使用。我检查的每个示例都在反序列化用户函数中使用User.findOne

到目前为止,我已禁用Passport会话的使用,我正在使用一个自定义中间件,在其中检查
req.session.user!=空
。如果是这种情况,用户已经登录,我点击
next()
。否则重定向到登录

以下是一些代码(为了简单起见,我删除了与问题无关的代码):

护照配置

var express = require('express'),
    session = require('express-session'),
    passport = require('passport'),
    LdapStrategy = require('passport-ldapauth');

var app = express();

var LdapStrategyOptions = {
  server: {
    url: '<url>',
    bindDN: '<dn>',
    bindCredentials: "<pwd>",
    searchBase: '<searchBase>',
    searchFilter: '<filter>'
  }
};
passport.use(new LdapStrategy(LdapStrategyOptions));

app.use(cookieParser());
app.use(session({
  store: new LokiStore({autosave: false}),
  resave: false,
  saveUninitialized: false
  secret: env.get("SESSION_SECRET")
}));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(passport.initialize());
// LOGIN ROUTE
app.get('/login',
  function(req, res) {
    res.render('login');
});

// LOGIN HANDLER ROUTE
app.post('/login',
  passport.authenticate('ldapauth', { session: false }),
  function(req, res) {
    req.session.userId = req.user.cn;
    req.session.user = {
      "userId": req.user.cn,
      "displayName": req.user.displayName
    };
  res.redirect('/');
});

// LOGOUT ROUTE
app.get('/logout',
  function(req, res) {
    req.session.destroy(function(err) {
      req.logout();
      res.redirect('/');
    });
});

// HOME ROUTE
app.get('/', isLoggedIn, function(req, res) {
   res.render('home');
});
var isLoggedIn = function(req, res, next) {
  if (req.session.user != null){
    console.log("is auth ok '" + req.session.user.userId +"'");
    return next();
  }

  console.log("redirect to auth/login");
  res.redirect('/auth/login');
}
IsLoggedIn中间件

var express = require('express'),
    session = require('express-session'),
    passport = require('passport'),
    LdapStrategy = require('passport-ldapauth');

var app = express();

var LdapStrategyOptions = {
  server: {
    url: '<url>',
    bindDN: '<dn>',
    bindCredentials: "<pwd>",
    searchBase: '<searchBase>',
    searchFilter: '<filter>'
  }
};
passport.use(new LdapStrategy(LdapStrategyOptions));

app.use(cookieParser());
app.use(session({
  store: new LokiStore({autosave: false}),
  resave: false,
  saveUninitialized: false
  secret: env.get("SESSION_SECRET")
}));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(passport.initialize());
// LOGIN ROUTE
app.get('/login',
  function(req, res) {
    res.render('login');
});

// LOGIN HANDLER ROUTE
app.post('/login',
  passport.authenticate('ldapauth', { session: false }),
  function(req, res) {
    req.session.userId = req.user.cn;
    req.session.user = {
      "userId": req.user.cn,
      "displayName": req.user.displayName
    };
  res.redirect('/');
});

// LOGOUT ROUTE
app.get('/logout',
  function(req, res) {
    req.session.destroy(function(err) {
      req.logout();
      res.redirect('/');
    });
});

// HOME ROUTE
app.get('/', isLoggedIn, function(req, res) {
   res.render('home');
});
var isLoggedIn = function(req, res, next) {
  if (req.session.user != null){
    console.log("is auth ok '" + req.session.user.userId +"'");
    return next();
  }

  console.log("redirect to auth/login");
  res.redirect('/auth/login');
}
我错过了什么?我的设置中是否存在任何安全错误? 感谢您的帮助

来自文档:

在典型的web应用程序中,用于验证用户身份的凭据仅在登录请求期间传输。如果身份验证成功,将通过用户浏览器中的cookie集建立和维护会话

每个后续请求将不包含凭据,而是标识会话的唯一cookie。为了支持登录会话,Passport将序列化和反序列化会话中的用户实例

基本上,
serializeUser
应该返回一个唯一的用户标识符,以便以后可以
反序列化user
返回到JSON中

因此,对于您的实现,您可能应该按照以下思路做一些事情:

免责声明:我没有LDAP方面的经验

passport.serializeUser(function(user, done) {
  //We can identify the user uniquely by the CN,
  //so we only serialize this into the session token.
  done(null, user.cn);
});

passport.deserializeUser(function(cn, done) {
  //Directly query LDAP.
  //I'm not sure passport caches the result (only calls deserializeUser for new sessions)
  //but worst case you can cache the result yourself.
  somehowLoadUserFromLDAPByCN(cn, function(err, user) {
    done(err, {
     userId: user.cn,
     displayName: user.displayName
    });
  });
});

如果您只需要一个id和一个显示名,那么将它们保持在会话中是完全可以的。您应该只在需要更多字段时加载完整的用户配置文件。

是否可能缺少
app.use(passport.session())?否。我从示例代码中删除了它,因为在编写时,我没有使用它,因为我无法理解应该在passport.deserializeUser()中编写什么。示例cose正是我发现的使其与自定义会话管理一起工作的方法!但问题是,我不想在每个请求上都使用LDAP(资源密集型流程)。数据库也是如此。为什么每次请求都要查询数据库?这正是我在passport框架中不理解的。我记不起passport是否处理此函数结果的缓存。您可以通过设置断点来检查自己,并查看是否在您已通过身份验证的情况下调用了断点。我的假设是不会(因为passport不知道您是否要缓存这些结果。您可以在这个函数中自己缓存结果,只有在缓存未命中时,才点击LDAP查询)。缓存的实现取决于您(内存、redis等)。即使您已经通过身份验证,也会在每个请求上调用反序列化用户。我仍然不知道这个函数的目的是什么。我究竟为什么要在每次请求时都点击auth系统(DB、LDAP、facebook服务)?如果我可以使用会话存储用户名、电子邮件和其他信息,为什么我要将用户配置文件缓存在数据库中?因为有时您的数据库包含有关该用户的其他信息(例如角色)