我对node还比较陌生,我正在尝试用passportjs创建一个简单的登录/注册系统。我有一个passport配置文件,在其中我将passport对象作为一个参数传递,如下所示。
我的passport配置文件:
var LocalStrategy = require('passport-local').Strategy;
var User = require('./../models/user');
var mysql = require('./../database/mysql_setup');
var mysqlPool = mysql.pool;
// expose this function to our app using module.exports
module.exports = function(passport) {
mysqlPool.getConnection(function(error, connection) {
if (error) throw error;
connection.query('USE vidyawxx_build2');
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and deserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.username);
});
// used to deserialize the user
passport.deserializeUser(function(username, done) {
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE username = " + connection.escape(username), function(err,rows){
done(err, rows[0]);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user whose username is the same as the forms username
// we are checking to see if the user trying to login already exists
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = "+connection.escape(username),function(err,rows){
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('error', 'This username is already in use.'));
} else {
// if there is no user with that username
// create the user
var newUserMysql = new User(username, password);
newUserMysql.generateHash(function(error, hash) {
if(error) {
return done(error);
}
var insertQuery = "INSERT INTO `"+mysql.dbSpecs.prefix+"users` ( username, password ) values (" + connection.escape(newUserMysql.username) +",'"+ hash +"')";
connection.query(insertQuery,function(err,rows){
if(err) {
return done(error);
}
return done(null, rows);
});
});
}
});
}
));
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = " + connection.escape(username), function(err,rows){
if (err) {
return done(err);
}
if (rows.length === 0) {
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
var newUser = new User(username, password);
newUser.compareHash(function(error, result) {
if(result) {
return done(null, rows[0]);
} else {
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // create the loginMessage and save it to session as flashdata
}
});
});
}
));
connection.release();
});
};
我的问题在于,如果我的mysql服务器由于任何原因而关闭,那么错误就会被抛出到我的第一行。我希望能够重定向到一个简单的页面,给他一个信息,如“数据库有问题,请稍后再试”。问题是,当我抛出错误时,我的应用程序只是关闭了,给任何访问者错误连接拒绝的响应。
这是我的app.js文件:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var passport = require('passport');
var passportConfig = require('./config/passport');
var session = require("express-session");
var flash = require("connect-flash");
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
passportConfig(passport);
app.use(session({
secret: "aPa1fgOed(&fjkKLN34%#$lpv@@",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 1000*60*15 } //15 minutes in milliseconds
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//create local vaariables for all our templates to use
app.use(function(req, res, next) {
res.locals.errors = req.flash("error");
res.locals.infos = req.flash("info");
res.locals.successes = req.flash("success");
next();
});
app.use('/', indexRouter);
app.use('/users', usersRouter);
// 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');
});
module.exports = app;
这就是说,由于错误是在我的passport配置文件中抛出的,它不遵循具有req、res和next参数的中间件约定,因此如何将用户重定向到上面提到的页面?
当然,我要再说一遍,这只涉及mysql连接错误。我知道我可以使用done()通过passport config方法返回其他错误,但是数据库连接错误发生在具有done参数的函数之外。
提前谢谢
1条答案
按热度按时间klsxnrf11#
看起来在仔细研究之后,我能想到的唯一解决方法是将查询合并到passport配置方法中,这样我就可以通过done()函数传回任何数据库连接错误;
这是我修改过的passport配置文件