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.user
。 res.locals.currentUser
仍然没有,但我暂时接受这个。
我正在使用 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.user
。 res.locals.currentUser
仍然没有,但我暂时接受这个。