Node/Express 服务器重启后如何使用 Passport 自动登录开发用户

How to automatically log in dev user after Node/Express server restart using Passport

我正在使用 Node/Express 进行个人项目,我相信您明白每次更改后重新启动服务器时都必须重新登录很烦人。

我正在使用 passport-local-mongoose 进行身份验证,一切正常。我只是在寻找一种让启动过程包括自动登录具有管理员角色的用户 'bob' 的方法,这样我就可以尝试我正在使用的路由,而不必每 5 次重新登录分钟。

我试过这个:


//set local variables middleware
app.use(function (req,res,next) {
    // req.user = {
    //  '_id':'6011d61a04abe04708edfb5f',
    //  'username':'bob'
    // }
    // req.user = User.findOne({username: 'bob'});
    req.user = User.authenticate()('bob','password');
    console.log(req.user);
    res.locals.currentUser = req.user;
    //set success flash message
    res.locals.success = req.session.success || "";
    //delete flash message after sending it to the page so it doesn't show again
    delete req.session.success;
    //set error flash message
    res.locals.error = req.session.error || "";
    //delete flash message after sending it to the page so it doesn't show again
    delete req.session.error;
    //continue on to the next function in the middlware/route chain
    next();
})

(请注意,我尝试了 3 种不同的方式将用户分配给 req.user),并且我已将它紧跟在 app.use(passport.session()) 之后,以及我的 [=15] 中的其他一些地方=] 文件,它似乎完全忽略了整个 app.use 函数。 console.log 没有 运行,而且我无法在任何路由中访问 currentUser

只是为了咯咯笑,这是我的全部app.js:

var createError = require('http-errors');
var express = require('express');
const bodyParser = require('body-parser');
var path = require('path');
const jwt = require('jsonwebtoken');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const mongoose = require('mongoose');
const User = require('./models/user');
const passport = require('passport');

// CHANGE: USE "createStrategy" INSTEAD OF "authenticate"
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

require('mongoose-type-url');



var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var booksRouter = require('./routes/books');

const app = express();

//connect to database
mongoose.connect(process.env.DATABASE_URL,{
    useNewUrlParser:true, 
    useUnifiedTopology:true,
  useFindAndModify: false,
  useCreateIndex:true
}).then(() => {
    console.log('Connected to Mongo DB');
}).catch(err => {
    console.log('Mongoose error: ',err);
});

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

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(require('express-session')({
  secret:"more things in the world",
  resave: false,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));


//set local variables middleware
app.use(function (req,res,next) {
    // req.user = {
    //  '_id':'6011d61a04abe04708edfb5f',
    //  'username':'bob'
  // }
  // req.user = User.findOne({username: 'bob'});
  req.user = User.authenticate()('bob','password');
  console.log(req.user);
    res.locals.currentUser = req.user;
    //set success flash message
    res.locals.success = req.session.success || "";
    //delete flash message after sending it to the page so it doesn't show again
    delete req.session.success;
    //set error flash message
    res.locals.error = req.session.error || "";
    //delete flash message after sending it to the page so it doesn't show again
    delete req.session.error;
    //continue on to the next function in the middlware/route chain
    next();
})

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/books', booksRouter);


if (app.get('env') == 'development'){ 
  require('dotenv').config(); 
};

app.use(async (req, res, next) => {
  if (req.headers["x-access-token"]) {
    const accessToken = req.headers["x-access-token"];
    const { userId, exp } = await jwt.verify(accessToken, process.env.JWT_SECRET);
    // Check if token has expired
    if (exp < Date.now().valueOf() / 1000) { 
    return res.status(401).json({ error: "JWT token has expired, please login to obtain a new one" });
    } 
    res.locals.loggedInUser = await User.findById(userId); next(); 
  } else { 
    next(); 
  } 
 });

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


let port = process.env.PORT;
if (port == null || port == "") {
  port = 8080;
}
app.listen(port, () => {
    console.log("server has started, listening on port "+port);
});

module.exports = app;

编辑:免责声明:我在发布此内容时添加了最后一次 User.authenticate 尝试,并假设它不会起作用,因为它在文件的其他地方不起作用。但显然它现在正在工作?然而,无法在其他路由中访问 currentUser 的问题仍然存在,但我至少可以解决这个问题。

原来我忘了 app.use 是中间件(它甚至在我在 class 的一个旧项目中使用它时的评论中也有)。它不会 运行 直到实际调用路由(任何路由)。它在服务器启动时 运行 并不像我发帖时最初想的那样。

因此,我能够在我需要的路径中很好地访问 req.userres.locals.currentUser 仍然没有,但我暂时接受这个。