为什么PassportJS会一直将我重定向到failureRedirect?

时间:2016-05-23 04:28:45

标签: node.js express passport.js passport-local

我尝试使用PassportJS来保护Web应用程序的某些路由。我正在使用Passport,ExpressJS和MongoDB。我发现在显然成功的身份验证之后,每次尝试访问其中一条受保护的路由都会被重定向到/login,就像登录失败一样。

我已经尝试制作一个新项目来尝试测试这一部分,并且我得到了相同的行为:有/authenticated路由,需要用户登录,以及/unauthenticated一个没有的。通过/login POST路由成功登录后,应将用户重定向到/authenticated;如果日志记录失败,则会将其重定向回/login

但是,在正确重定向到/authenticated后,用户会被重定向回/login

screenshoot showing the redirects

我在这里可能做错了什么?用户已成功登录,为什么要将其重定向回failureRedirect

所有相关代码都在this GitHub repository中。我接下来会包含server.js文件和登录表单:

<form action="/login" method="post">
  <label for=login_name>username</label>
  <input type="text" name="username"><br/>
  <label for=password>password</label>
  <input type="password" name="password"><br/>
  <input type="submit" value="Go">
</form>

这是Express配置:

app.set('port', (process.env.PORT || 3004));

app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*'); // Permissive CORS header
  res.setHeader('Cache-Control', 'no-cache');
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(morgan('combined'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());

这是Passport设置:

function verify (username, password, done) {

  db.collection("users").findOne({ username: username })
  .then(
    doc => {
      if (!doc) {
        console.log(`User ${username} doesn't exist`);
        done(null, false, { message: "User doesn't exist" });
      }
      if (doc.password != password) {
        console.log(`${password} is the wrong password`);
        done(null, false, { message: "Wrong password" });
      }
      else { 
        console.log("AOK"); 
        done(null, doc); 
      }
    }, 
    reason => done(reason)
  );
}

passport.use(new LocalStrategy(verify));

passport.serializeUser(function(user, done) {
  console.log("Serialize here, got " + JSON.stringify(user));
  done(null, user._id);
});
passport.deserializeUser(function(id, done) {
  db.collection("users").findOne({ _id: id })
  .then(
    doc => done(null, doc),
    reason => done(reason)
  );
});

这些是我的路线:

app.get("/login", (req, res) => {
  fs.readFile("./login.html", "utf8", (err, data) => {
    if (err) throw err;
    res.send(data);
})});

app.post("/login", passport.authenticate("local", {
  failureRedirect: '/login',
}), (req, res) => { res.redirect("/authenticated")}); 

var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn("/login");
app.get("/authenticated", ensureLoggedIn, (req, res) => res.send("o hai"));
app.get("/unauthenticated", (req, res) => res.send("o hai"));

app.listen(app.get('port'), () => {
  console.log('Server started: http://localhost:' + app.get('port') + '/');
});

此外,这些是我使用的每个库的版本:

 "dependencies": {
    "body-parser": "^1.15.1",
    "connect-ensure-login": "^0.1.1",
    "connect-flash": "^0.1.1",
    "cookie-parser": "^1.4.2",
    "express": "^4.13.4",
    "express-session": "^1.13.0",
    "mongodb": "^2.1.19",
    "morgan": "^1.7.0",
    "passport": "^0.3.2",
    "passport-local": "^1.0.0",
    "path": "^0.12.7"
  },

PD:我只使用明文密码进行此小型测试,而且远离生产数据库。

1 个答案:

答案 0 :(得分:1)

deserializeUser()作为字符串传递id,但对于针对_id的直接MongoDB查询,您需要先将其转换为ObjectId

passport.deserializeUser(function(id, done) {
  db.collection("users").findOne({ _id: mongodb.ObjectId(id) })
  .then(
    doc => done(null, doc),
    reason => done(reason)
  );
});