Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.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 如何加上「;“记住我”;使用passport访问我的应用程序_Node.js_Express_Passport.js - Fatal编程技术网

Node.js 如何加上「;“记住我”;使用passport访问我的应用程序

Node.js 如何加上「;“记住我”;使用passport访问我的应用程序,node.js,express,passport.js,Node.js,Express,Passport.js,我需要一个“记住我”复选框时,登录喜欢。 在使用passport之前,我添加了一个中间件 app.use(function(req, res, next) { if (req.method == 'POST' && req.url == '/login') { if (req.body.rememberme) { req.session.cookie.maxAge = 1000 * 60 * 3; } else { req.sessio

我需要一个“记住我”复选框时,登录喜欢。 在使用passport之前,我添加了一个中间件

app.use(function(req, res, next) {
  if (req.method == 'POST' && req.url == '/login') {
    if (req.body.rememberme) {
      req.session.cookie.maxAge = 1000 * 60 * 3;
    } else {
      req.session.cookie.expires = false;
    }
  }
  next();
});
app.use(passport.initialize());
app.use(passport.session());
req.body.rememberme
为true时,我无法登录,当
req.body.rememberme
为false时,会记住用户。 我还尝试了连接确保登录,但仍然是错误的

还有一个问题:我应该什么时候删除数据库中的cookies,如何删除

:)

其他代码与护照指南完全相同

路线:

app.get('/', passport.authenticate('local', {
  failureRedirect: '/login'
}), function(req, res) {
  res.redirect('/user/home');
});
app.post('/login', passport.authenticate('local', {
  failureRedirect: '/login'
}), function(req, res) {
  res.redirect('/user/home');
});
会议:

passport.serializeUser(function(user, done) {
  var CreateAccessToken = function() {
    var token = user.GenerateSalt();
    User.findOne({
      accessToken: token
    }, function(err, existingUser) {
      if (err)
        return done(err);
      if (existingUser) {
        CreateAccessToken();
      } else {
        user.set('accessToken', token);
        user.save(function(err) {
          if (err)
            return done(err);
          return done(null, user.get('accessToken'));
        })
      }
    });
  };
  if (user._id)
    CreateAccessToken();
});
passport.deserializeUser(function(token, done) {
  User.findOne({
    accessToken: token
  }, function(err, user) {
    if (err)
      return done(err);
    return done(err, user);
  });
});
战略:

passport.use(new LocalStrategy(function(userId, password, done) {
  User.findOne().or([{
    username: userId
  }, {
    email: userId
  }]).exec(function(err, user) {
    if (err)
      return done(err);
    if (!user) {
      return done(null, false, {
        message: 'Invalid password or username'
      });
    }
    if (user.Authenticate(password)) {
      return done(null, user);
    } else {
      return done(null, false, {
        message: 'Invalid password or username'
      });
    }
  });
}));

我注意到Express只会在哈希值更改时更新cookie。因此,我修改了中间件中的代码

app.use(function(req, res, next) {
  if (req.method == 'POST' && req.url == '/login') {
    if (req.body.rememberme) {
      req.session.cookie.maxAge = 1000 * 60 * 3;
      req.session._garbage = Date();
      req.session.touch();
    } else {
      req.session.cookie.expires = false;
    }
  }
  next();
});
现在我可以用“记住我”登录,但它只能在Ubuntu上的chromium和firefox上使用。在Win7和Android上,我仍然无法使用chrome和firefox上的“记住我”复选框登录

我在win7上的chrome上发布到“/login”时检查了响应标题,它与Ubuntu上的“Set Cookie”字段相同,为什么不能工作


时间不同步…所以我发布了一个额外的时间字段

$('#login').ajaxForm({
  beforeSubmit: function(arr, $form, option) {
    arr.push({
      name: '__time',
      value: (new Date()).toGMTString()
    });
  }
});
以及“记忆”中间件:

app.use(function(req, res, next) {
  if (req.method == 'POST' && req.url == '/login') {
    if (req.body.rememberme) {
      req.session.cookie.maxAge = moment(req.body.__time).add('m', 3) - moment();
      req.session._garbage = Date();
      req.session.touch();
    } else {
      req.session.cookie.expires = false;
    }
  }
  next();
});

确保
app.use(express.bodyParser())
位于中间件之上,因为您依赖
req.body.rememberme

我遇到了与您完全相同的问题。以下代码适用于我:

app.post("/login", passport.authenticate('local',
    { failureRedirect: '/login',
      failureFlash: true }), function(req, res) {
        if (req.body.remember) {
          req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // Cookie expires after 30 days
        } else {
          req.session.cookie.expires = false; // Cookie expires at end of session
        }
      res.redirect('/');
});

现在有了一个Passport策略来添加Jared Hanson编写的“记住我”功能


这是通过在下一个会话开始时使用的每个会话中发出一个唯一的RememberMe令牌来实现的(使其失效以备将来使用)。因此,这可能是一个更安全的解决方案。

这难道不是完全错误的吗?如果
rememberme==true
则表示cookie不应过期?您应该发布更多的代码,因为您需要的不仅仅是这三个中间件。如果cookie过期(在本例中为3分钟),则cookie将成为会话cookie(在浏览器会话完成时过期)。但是我同意:需要更多的代码。这个代码非常混乱。你应该把关注点分开。
序列化
反序列化
函数仅用于通过id获取用户(使用数据库id)并序列化到会话cookie(如果您担心,id不会以明文形式存在)。不要混入一些可疑的安全措施code@pfried我不太清楚passport local是如何工作的,就像他们的指南一样,我在
序列化
中制作了一个唯一的令牌,并发现用户在
反序列化
中获得了令牌,但我不清楚何时调用这些函数。我最近也一直在做这方面的工作,这对我有点帮助:我将示例时间从3分钟(比大多数会话都少)编辑到30天。我认为3分钟是不记得我的模式,
…expires=false表示永不过期。@rjmunro为什么要重定向到“/”?这是根路径或“login/”这不是我的代码-我刚刚添加了一些注释,但它看起来像是在您登录后重定向到站点的根目录。这个答案写在前一段时间:-如果你的应用程序是KoaJS应用程序,对我来说很好。它实际上是JaydHhanson的原始回购的一个分支,它只是为KoA.js应用程序添加了一个支持(同时),也值得注意的是,对于真正的“记住我”,您需要对令牌进行某种长期持久性,无论是在缓存还是数据库中,否则服务器会将它们存储在内存中。您希望能够重新启动服务器,并且记住我的令牌仍然有效