身份验证后重定向到 Passport.js 中的上一页(不重复)Node.js
Redirecting to previous page in Passport.js after authentication (not duplicate) Node.js
当我被重定向到登录时,我正在尝试重定向回页面。我正在使用 Passport 和 connect-ensure-login,并且登录有效,但是,不得不重新单击 link(如果您没有登录,它会将您重定向到主页,但 link 有一个查询字符串)。有没有办法在成功登录后添加重定向 URL?
重定向 URL 需要是动态的,因为它是查询字符串,不依赖于用户的 ID 或类似的东西。
这是我的服务器端代码片段(如果您需要任何其他片段,请告诉我,因为我的 app.js 有 224 行,我不想 post 那样) .
app.js
:
let express = require( 'express' );
let app = express();
const expressSession = require('express-session')({
secret: `secret`,
resave: false,
saveUninitialized: false
});
app.use(expressSession);
const passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());
let path = require( 'path' );
const passportLocalMongoose = require('passport-local-mongoose');
const connectEnsureLogin = require('connect-ensure-login');
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
const Mixed = mongoose.Schema.Types.Mixed;
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/db', { useNewUrlParser: true, useUnifiedTopology: false });
const Schema = mongoose.Schema;
const UserDetail = new Schema({
username: String,
email: Mixed,
password: String,
verified: Boolean
});
UserDetail.plugin(passportLocalMongoose);
const UserDetails = mongoose.model('userInfo', UserDetail, 'userInfo');
passport.use(UserDetails.createStrategy());
passport.serializeUser(UserDetails.serializeUser());
passport.deserializeUser(UserDetails.deserializeUser());
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));
app.use( '/login', express.static( path.join( __dirname, 'login' ) ) );
app.get( '/', connectEnsureLogin.ensureLoggedIn(), ( req, res ) => {
res.sendFile( __dirname + '/index.html' );
});
app.post('/login', (req, res, next) => {
passport.authenticate('local',
(err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/login?info=' + info);
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
});
app.get('/login', (req, res) => {
res.sendFile('login/login.html', { root: __dirname })
});
app.get('/register', (req, res) => {
res.sendFile('login/register.html', { root: __dirname })
});
app.get('/user', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.send({user: req.user})
})
app.post('/register', (req, res) =>{
UserDetails.register({ username: req.body.username, active: false, email: req.body.email }, req.body.password)
res.redirect('/login')
})
有没有办法:
- 使用
connectEnsureLogin.ensureLoggedIn()
时在会话中保存查询字符串?
- 或者以另一种方式保存查询字符串并在重定向时读取它?
我是 Node.js 的新手,所以我按照一个例子来让登录工作(抱歉,我现在没有这个例子,我不知道我在哪里找到它而且我没有'不要保存它的副本)。
此外,这个问题不会重复 this SO 问题,因为我想不出如何使用我当前的中间件 connectEnsureLogin.ensureLoggedIn() 来实现答案。如果没有,请告诉我如何实现@Chovy 的答案以使用我目前的情况。
非常感谢!!!
编辑:
我认为它与 connectEnsureLogin 中的 redirectTo
有关,但是,我无法读取查询字符串。我试图将 redirectTo
设置为 req.url
但我的服务器出现以下错误:
returnTo: req.query
^
ReferenceError: req is not defined
有办法吗?谢谢
遗憾的是,connectEnsureLogin
不提供您的情况所需的自定义,但是,一个简单的中间件功能可以满足您的需求。
在顶部,定义一个中间件函数并设置一个名为 RedirectTo 的会话 cookie:
function auth (req, res, next) {
if (req.isAuthenticated()) {
// user is authenticated, so we do not need to redirect them.
return next();
} else {
// user is not authenticated, so add a session cookie telling our server where to redirect to.
req.session.redirectTo = req.url;
// redirect to login with cookie set
res.redirect('/login');
}
}
你可以这样使用中间件:
app.get( '/', auth, ( req, res ) => {
// ^^^^ notice that we use our middleware instead
res.sendFile( __dirname + '/index.html' );
})
然后,您可以像这样在 post 请求处理程序中读取该会话 cookie:
app.post('/login', (req, res, next) => {
// authentication like normal
passport.authenticate('local',(err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/login?info=' + info);
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
// this is the special part
// redirect the user to the session cookie if it exists
var redirectTo = req.session.redirectTo || '/';
// delete the session cookie so it is not present on the next request
delete req.session.redirectTo;
// redirecting the user to where they want to go
res.redirect(redirectTo || '/');
});
})(req, res, next);
});
当我被重定向到登录时,我正在尝试重定向回页面。我正在使用 Passport 和 connect-ensure-login,并且登录有效,但是,不得不重新单击 link(如果您没有登录,它会将您重定向到主页,但 link 有一个查询字符串)。有没有办法在成功登录后添加重定向 URL?
重定向 URL 需要是动态的,因为它是查询字符串,不依赖于用户的 ID 或类似的东西。
这是我的服务器端代码片段(如果您需要任何其他片段,请告诉我,因为我的 app.js 有 224 行,我不想 post 那样) .
app.js
:
let express = require( 'express' );
let app = express();
const expressSession = require('express-session')({
secret: `secret`,
resave: false,
saveUninitialized: false
});
app.use(expressSession);
const passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());
let path = require( 'path' );
const passportLocalMongoose = require('passport-local-mongoose');
const connectEnsureLogin = require('connect-ensure-login');
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
const Mixed = mongoose.Schema.Types.Mixed;
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/db', { useNewUrlParser: true, useUnifiedTopology: false });
const Schema = mongoose.Schema;
const UserDetail = new Schema({
username: String,
email: Mixed,
password: String,
verified: Boolean
});
UserDetail.plugin(passportLocalMongoose);
const UserDetails = mongoose.model('userInfo', UserDetail, 'userInfo');
passport.use(UserDetails.createStrategy());
passport.serializeUser(UserDetails.serializeUser());
passport.deserializeUser(UserDetails.deserializeUser());
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));
app.use( '/login', express.static( path.join( __dirname, 'login' ) ) );
app.get( '/', connectEnsureLogin.ensureLoggedIn(), ( req, res ) => {
res.sendFile( __dirname + '/index.html' );
});
app.post('/login', (req, res, next) => {
passport.authenticate('local',
(err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/login?info=' + info);
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
});
app.get('/login', (req, res) => {
res.sendFile('login/login.html', { root: __dirname })
});
app.get('/register', (req, res) => {
res.sendFile('login/register.html', { root: __dirname })
});
app.get('/user', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.send({user: req.user})
})
app.post('/register', (req, res) =>{
UserDetails.register({ username: req.body.username, active: false, email: req.body.email }, req.body.password)
res.redirect('/login')
})
有没有办法:
- 使用
connectEnsureLogin.ensureLoggedIn()
时在会话中保存查询字符串? - 或者以另一种方式保存查询字符串并在重定向时读取它?
我是 Node.js 的新手,所以我按照一个例子来让登录工作(抱歉,我现在没有这个例子,我不知道我在哪里找到它而且我没有'不要保存它的副本)。
此外,这个问题不会重复 this SO 问题,因为我想不出如何使用我当前的中间件 connectEnsureLogin.ensureLoggedIn() 来实现答案。如果没有,请告诉我如何实现@Chovy 的答案以使用我目前的情况。
非常感谢!!!
编辑:
我认为它与 connectEnsureLogin 中的 redirectTo
有关,但是,我无法读取查询字符串。我试图将 redirectTo
设置为 req.url
但我的服务器出现以下错误:
returnTo: req.query
^
ReferenceError: req is not defined
有办法吗?谢谢
遗憾的是,connectEnsureLogin
不提供您的情况所需的自定义,但是,一个简单的中间件功能可以满足您的需求。
在顶部,定义一个中间件函数并设置一个名为 RedirectTo 的会话 cookie:
function auth (req, res, next) {
if (req.isAuthenticated()) {
// user is authenticated, so we do not need to redirect them.
return next();
} else {
// user is not authenticated, so add a session cookie telling our server where to redirect to.
req.session.redirectTo = req.url;
// redirect to login with cookie set
res.redirect('/login');
}
}
你可以这样使用中间件:
app.get( '/', auth, ( req, res ) => {
// ^^^^ notice that we use our middleware instead
res.sendFile( __dirname + '/index.html' );
})
然后,您可以像这样在 post 请求处理程序中读取该会话 cookie:
app.post('/login', (req, res, next) => {
// authentication like normal
passport.authenticate('local',(err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/login?info=' + info);
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
// this is the special part
// redirect the user to the session cookie if it exists
var redirectTo = req.session.redirectTo || '/';
// delete the session cookie so it is not present on the next request
delete req.session.redirectTo;
// redirecting the user to where they want to go
res.redirect(redirectTo || '/');
});
})(req, res, next);
});