身份验证后重定向到 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')
})

有没有办法:

  1. 使用 connectEnsureLogin.ensureLoggedIn() 时在会话中保存查询字符串?
  2. 或者以另一种方式保存查询字符串并在重定向时读取它?

我是 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);
});