为什么 PassportJS 一直将我重定向到 failureRedirect?
Why does PassportJS keep redirecting me to failureRedirect?
我正在尝试使用 PassportJS 来保护 Web 应用程序的某些路由。我正在使用 Passport、ExpressJS 和 MongoDB。我发现在明显成功的身份验证之后,每次访问这些受保护路由之一的尝试都会再次重定向到 /login
,就好像登录失败一样。
我已经尝试创建一个新项目来尝试测试这部分,但我得到了相同的行为:有一个 /authenticated
路由,需要用户登录,并且一个 /unauthenticated
没有的。通过 /login
POST 路由成功登录后,用户应该被重定向到 /authenticated
;如果记录不成功,他们将被重定向回 /login
.
但是,在正确重定向到 /authenticated
后,用户被重定向回 /login
!
我可能在这里做错了什么?用户已成功登录,为什么他们被重定向回 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: 我只在这个小测试中使用 clear-text 密码,而且离生产数据库还很远。
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)
);
});
我正在尝试使用 PassportJS 来保护 Web 应用程序的某些路由。我正在使用 Passport、ExpressJS 和 MongoDB。我发现在明显成功的身份验证之后,每次访问这些受保护路由之一的尝试都会再次重定向到 /login
,就好像登录失败一样。
我已经尝试创建一个新项目来尝试测试这部分,但我得到了相同的行为:有一个 /authenticated
路由,需要用户登录,并且一个 /unauthenticated
没有的。通过 /login
POST 路由成功登录后,用户应该被重定向到 /authenticated
;如果记录不成功,他们将被重定向回 /login
.
但是,在正确重定向到 /authenticated
后,用户被重定向回 /login
!
我可能在这里做错了什么?用户已成功登录,为什么他们被重定向回 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: 我只在这个小测试中使用 clear-text 密码,而且离生产数据库还很远。
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)
);
});