Регистрация по паспорту просто вращается постоянно

#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);
            }
        })        
    });