gpt4 book ai didi

mysql - 带有exress处理中间件外部数据库连接错误的Node.js

转载 作者:行者123 更新时间:2023-11-30 21:42:22 26 4
gpt4 key购买 nike

我是 node 的新手,我正在尝试使用 passportjs 创建一个简单的登录/注册系统。我有我的护照配置文件,我在其中将护照对象作为参数传递,如下所示。

我的护照配置文件:

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 服务器因任何原因关闭,我的第一行就会抛出错误。我希望能够将我的用户重定向到一个简单的页面,该页面会向他显示一条消息,例如“数据库出现问题,请稍后再试”。问题是,当我抛出错误时,我的应用程序只是关闭,向任何访问者提供 ERR_CONNECTION_REFUSED 响应。(我目前正在本地工作。

这是我的 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-config 文件中抛出的,它不遵循具有 req、res 和 next 参数的中间件约定,我如何才能优雅地将我的用户重定向到如上所述的页面?

为了确定,我再说一遍,这只涉及 mysql 连接错误。我知道我可以使用 done() 通过我的 passport-config 方法返回其他错误,但是数据库连接错误发生在带有 done 参数的函数之外。

提前致谢

最佳答案

看起来在深入研究之后,我唯一能想到的解决方法是将查询合并到护照配置方法中,这样我就可以通过 done() 函数传回任何数据库连接错误;

这是我修改过的护照配置文件

// load all the things we need
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) {

//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) {
mysqlPool.getConnection(function(dbError, connection) {

if(dbError) {
return done(dbError);
}

connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE username = " + connection.escape(username), function(err,rows){
if(err) {
done(err);
connection.release();
return;
}
connection.release();
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
mysqlPool.getConnection(function(dbError, connection) {

if(dbError) {
return done(dbError);
}

connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = "+connection.escape(username),function(err,rows){

if (err) {
connection.release();
return done(err);
}

if (rows.length) {
connection.release();
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) {
connection.release();
return done(error);
}

var insertQuery = "INSERT INTO `"+mysql.dbSpecs.prefix+"users` ( username, password ) values (" + connection.escape(newUserMysql.username) +",'"+ hash +"')";

mysqlPool.query(insertQuery,function(err,rows){
if(err) {
connection.release();
return done(error);
}
connection.release();
return done(null, rows);
});

});

}
connection.release();
});

});
}
));

// =========================================================================
// 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

mysqlPool.getConnection(function(dbError, connection) {
if(dbError) {
return done(dbError);
}
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = " + connection.escape(username), function(err,rows){

if (err) {
connection.release();
return done(err);
}
if (rows.length === 0) {
connection.release();
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) {
connection.release();
return done(null, rows[0]);
} else {
connection.release();
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // create the loginMessage and save it to session as flashdata
}
});

});
});
}
));


};

关于mysql - 带有exress处理中间件外部数据库连接错误的Node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50985157/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com