如何使用护照将"记住我"添加到我的应用程序中

Qin*_*Yun 25 node.js express passport.js

我喜欢登录时需要"记住我"复选框.我在使用护照之前添加了一个中间件

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());
Run Code Online (Sandbox Code Playgroud)

如果req.body.rememberme为true,我无法登录,并且当req.body.rememberme错误时记住用户.我也试过connect-ensure-login,但仍然错了.

还有一个问题:我应该何时删除数据库中的cookie以及如何删除?

:)

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

路线:

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');
});
Run Code Online (Sandbox Code Playgroud)

会议:

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

和战略:

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'
      });
    }
  });
}));
Run Code Online (Sandbox Code Playgroud)

我注意到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();
});
Run Code Online (Sandbox Code Playgroud)

现在我可以使用"记住我"登录,但它只适用于Ubuntu上的chrome和firefox.我仍然无法使用Chrome和Firefox上的"记住我"复选框登录Win7和Android.

我在win7上使用chrome上的"/ login"检查了响应头,它在Ubuntu上有与"Set-Cookie"相同的字段,为什么它不起作用?


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

$('#login').ajaxForm({
  beforeSubmit: function(arr, $form, option) {
    arr.push({
      name: '__time',
      value: (new Date()).toGMTString()
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

和"RememberMe"中间件:

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();
});
Run Code Online (Sandbox Code Playgroud)

BOC*_*BOC 33

我和你有完全相同的问题.以下代码适用于我:

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('/');
});
Run Code Online (Sandbox Code Playgroud)


tcm*_*ore 6

现在有一个Passport策略用于添加由Jared Hanson编写的Remember Me功能.

https://github.com/jaredhanson/passport-remember-me

这通过在下一个开始时消耗的每个会话期间发出唯一的remember-me令牌(使其在将来使用时无效)来工作.因此,这可能是更安全的解决方案.

  • 还值得注意的是,对于真正的“记住我”——您需要某种长期的令牌持久性,无论是在缓存中还是数据库中——否则服务器会将它们存储在内存中。您希望能够重新启动服务器,并且记住我的令牌仍然有效 (3认同)

Pla*_*ato 2

确保将其app.use(express.bodyParser())放置在您的中间件之上,因为您所依赖的req.body.rememberme