【问题标题】:passportjs: user undefined, req.isAuthenticated() is falsepassportjs:用户未定义,req.isAuthenticated() 为假
【发布时间】:2018-03-14 02:23:23
【问题描述】:

注意:有很多类似的问题,但我已经解决了所有问题,但没有一个解决方案有效。

嗨, 网上的所有解决方法都试过了,bug依旧存在。

我正在构建一个简单的 CRUD 应用程序,我目前正在努力处理 passportjs 的 req.isAuthenticated()。 用户肯定是经过身份验证的,因为passport.authenticate 中的console.log(req.user) 返回用户对象,而req.session.passport 有用户ID。

尽管重定向之后,即使重定向是异步的,用户也是未定义的并且 req.session.passport 是空的。就好像会话被重置了一样。

代码如下:

app.js

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');

var index = require('./routes/index');
var users = require('./routes/users');

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

app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

app.use(express.static(path.join(__dirname, 'public')));
app.use('/bootstrap', express.static(path.join(__dirname + '/node_modules/bootstrap/dist')));

app.use(session({
  secret: 'keyboard cat',
  resave: true,
  saveUninitialized: true,
  cookie: {
    maxAge: 5 * 60 * 1000
  }
}));

app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

app.use(function(req, res, next) {
  res.locals.messages = require("express-messages")(req, res);
  next();
});

app.get('*', function(req, res, next) {
  console.log(req.method, ":", req.url);
  res.locals.user = req.user || null;
  next();
});

app.use("/", index);
app.use("/users", users);

var port = 4000;
app.listen(port);
module.exports = app;

index.js

var express = require('express');
var router = express.Router();

router.get('/', isLoggedIn, function(req, res) {
  if (req.user) {
    console.log(req.user.username);
  }
  res.render('homepage');
});

function isLoggedIn(req, res, next) {
  console.log("passport: ", req.session.passport); //passport:{}
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect('/users/login');
}

module.exports = router;

users.js

var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('usersDB', ['users']);
var bcrypt = require('bcryptjs');
var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy;​
router.get('/login', function(req, res) {
  res.render('login');
});​
router.get('/signup', function(req, res) {
  res.render('signup');
});​
router.post('/signup', function(req, res) {
  db.users.findOne({
    username: req.body.name
  }, function(err, user) {
    if (err) {
      return done(err);
    }
    if (user) {
      console.log("nope");
      req.flash("error", "Username taken. Choose a different username.");
      return res.redirect('/users/signup');
    }
    var password = req.body.password;
    bcrypt.genSalt(10, function(err, salt) {
      if (err) {
        return done(err);
      }
      bcrypt.hash(password, salt, function(err, hash) {
        if (err) {
          return done(err);
        }
        var user = {
          username: req.body.name,
          email: req.body.email,
          phone: req.body.phone,
          password: hash
        }
        db.users.insert(user, function(err, result) {
          if (err) {
            return done(err);
          }
          console.log("registered", user)
          res.render("homepage", {
            user: user
          });
        });
      });
    });
  });
}); //sorry for the callback hell..works fine
​​
passport.serializeUser(function(user, done) {
  return done(null, user._id);
});​
passport.deserializeUser(function(id, done) {
  db.users.findOne({
    id: mongojs.ObjectId(id)
  }, function(err, user) {
    return done(err, user);
  });
});​
passport.use('loginStrategy', new LocalStrategy({
    passReqToCallback: true,
    usernameField: 'username',
    passwordField: 'password'
  },
  function(req, username, password, done) {
    db.users.findOne({
      username: username
    }, function(err, user) {
      if (err) {
        return done(err);
      }
      if (!user) {
        return done(null, false, req.flash('error', "Invalid username."));
      }
      bcrypt.compare(password, user.password,
        function isMatch(err, isMatch) {
          if (err) {
            return done(err);
          }
          if (!isMatch) {
            return done(null, false, req.flash('error', "Oops. Incorrect password."));
          }
          return done(null, user, req.flash('success', "Welcome " + user.username + ", you are now logged in."));
        });
    });
  }​));​
router.post('/login', function(req, res, next) {
  passport.authenticate('loginStrategy', function(err, user, info) {
    if (info) {
      req.flash('error', info.message);
    }
    if (err) {
      return next(err);
    }
    if (!user) {
      return res.redirect('/users/login');
    }
    req.logIn(user, function(err) {
      if (err) {
        return next(err);
      }
      //callback redirect after saving session.
      req.session.save(function() {
        console.log(req.session.passport); //{ user: 59ceb263dae7a4270087ae57 }
        res.redirect('/');
      });
    });
  })(req, res, next);
});​
router.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/users/login');
});​
module.exports = router;

我非常感谢一些帮助,因为这似乎是一个常见的错误,但没有一种解决方法对我有用。

【问题讨论】:

    标签: javascript node.js session express passport.js


    【解决方案1】:

    这似乎与您用于存储用户凭据的方法有关。请注意,Chrome 和 IE 在本地存储和会话存储方面有不同的特点。在 chrome 中试试这个,Passport JS 会将响应存储在本地或会话存储中 - 您应该询问这些存储机制以验证用户的凭据是否在其中。

    在 chrome 中,转到 F12 调试工具并查看您的会话和本地存储:

    请告诉我们您使用的浏览器,如果使用 Chrome 会有所不同。

    【讨论】:

    • 感谢您的回复。我开始使用 chrome V61.0.3163.100,但也不适用于 Firefox。签入会话和本地存储。两者都是空的,令人费解..
    猜你喜欢
    • 2017-07-10
    • 2019-10-11
    • 1970-01-01
    • 2018-12-19
    • 2021-08-16
    • 1970-01-01
    • 2013-10-17
    • 2018-08-06
    • 2017-12-09
    相关资源
    最近更新 更多