#node.js #express #passport.js
#node.js #экспресс #passport.js
Вопрос:
Я использую Passportjs, и после того, как я зарегистрируюсь, и он отправляет запрос post, я никогда не получаю ответ. Вот конфигурация паспорта, которую я использую:
// config/passport.js
require('dotenv').config();
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var mysql = require('mysql');
var bcrypt = require('bcryptjs');
var connection = mysql.createConnection({
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASS,
port: process.env.DBPORT,
database: process.env.DB
});
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
getUser(id, function (response) {
done(err, response);
})
});
// =========================================================================
// 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 : 'email',
passwordField : 'pass',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
async function(req, email, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
userExists(email, async function(resp) {
console.log(resp)
if (resp) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that username
// create the user
var pass = await bcrypt.hash(password, 10)
var newUserMysql = {
email: email,
password: pass,
fName: req.body.fName,
lName: req.body.lName,
practice: req.body.practice,
};
var insertQuery = `INSERT INTO Users(first_name, last_name, role, email, password, practice) VALUE (?, ? ,?, ?, ?, ?)`;
connection.query(insertQuery,[newUserMysql.fName,newUserMysql.lName, 0, newUserMysql.email, newUserMysql.password, newUserMysql.practice],function(err, rows) {
if(err) console.log(err)
newUserMysql.role = 0;
console.log(newUserMysql)
return done(null, newUserMysql);
});
}
})
})
);
// =========================================================================
// 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, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM Users WHERE email = ?",[email], function(err, rows){
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!bcrypt.compare(password, rows[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
})
);
};
function userExists(data, callback) {
const sql = `SELECT * FROM Users where email = ?`;
connection.query(sql, [data], function (err, resp) {
console.log(resp.length)
if (resp.length < 1) {
return callback(false)
}
return true;
})
}
function getUser(data, callback) {
const userSql =`SELECT * FROM Users where userId = ?`;
connection.query(userSql, [data], function (err, resp) {
if (resp) {
console.log(resp)
return callback(resp[0]);
}
return null;
})
}
Я вижу, что все отображается в БД нормально. Я думаю, что что-то не так с тем, как я сериализую / десериализирую пользователя. Но я не уверен. Также вот мои маршруты и способы их настройки:
// app/routes.js
module.exports = function(app, passport) {
// =====================================
// HOME PAGE (with login links) ========
// =====================================
app.get('/', function(req, res) {
res.render('index.ejs'); // load the index.ejs file
});
// =====================================
// LOGIN ===============================
// =====================================
// show the login form
app.get('/login', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/login', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}),
function(req, res) {
console.log("hello");
if (req.body.remember) {
req.session.cookie.maxAge = 1000 * 60 * 3;
} else {
req.session.cookie.expires = false;
}
res.redirect('/');
});
// =====================================
// SIGNUP ==============================
// =====================================
// show the signup form
app.get('/signup', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('signup.ejs', { message: req.flash('signupMessage') });
});
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
// =====================================
// PROFILE SECTION =========================
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', {
user : req.user // get the user out of session and pass to template
});
});
// =====================================
// LOGOUT ==============================
// =====================================
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
};
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
В моей консоли я вижу, где выполняются эти запросы:
POST /signup 302 445.782 ms - 60
GET /profile - - ms - -
GET /profile - - ms - -
POST /signup - - ms - -
POST /signup - - ms - -
POST /signup - - ms - -
POST /signup - - ms - -
Ответ №1:
На основе функции userExists похоже, что обратный вызов getUser неполон.
passport.deserializeUser(function(id, done) {
getUser(id, function (response) {
if (response) {
done(null, response);
}
})
});