Passport.authenticate()不显示即时消息

时间:2018-08-25 14:49:51

标签: node.js passport.js connect-flash

Goodday

我正在关注[this](https://www.youtube.com/watch?v=iX8UhDOmkPE&t=682s“登录并认证应用”)教程。一个区别是我使用的是MySQL而不是猫鼬。

在尝试登录时,我要刷新消息。例如“未知的用户名”。

不幸的是,这种情况没有发生,并且在模块通行证中硬编码的消息“凭据丢失”也不起作用。

server.js

// modules required here

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookiesParser());
app.use(session({
secret: 'pussycat',
saveUninitialized: true,
resave: true
}));

// Express Validator
app.use(expressValidator({
    errorFormatter: function (param, msg, value) {
        var namespace = param.split('.')
        , root = namespace.shift()
        , formParam = root;

        while (namespace.length) {
            formParam += '[' + namespace.shift() + ']';
        }
        return {
            param: formParam,
            msg: msg,
            value: value
        };
    },
    customValidators: {
        myCustomFunc: function (value) {
            return false;
        }
    }
}));

/**
 * Create server
 */
http.createServer(app).listen(port);
console.log("Server listening on port " + port);

/**
 * Connect to database
 */
var connection = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "*****",
    database: '********'
});

/**
 * Print out if the connection was succesful
 */
connection.connect(function (error) {
    if (!!error) {
        console.log("Error occured while connecting to database");
    }
    else {
        console.log("Connected to Database!");
    }
});

/**
 * Serve pages and set default directory
 */
app.use(express.static(__dirname + './../client/'));

/**
 * The views to switch between on the webpage
 */
app.set("views", path.join(__dirname + './../client/views'));

/**
 * set handlebars as template view engine
 */
app.engine('handlebars', exphbs({ defaultLayout: '../../../client/views/layouts/loginLayout' }));
app.set("view engine", "handlebars");

// make sure initialize is below  serving pages and setting a default directory
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

// Global Vars
app.use(function (req, res, next) {
    res.locals.success_msg = req.flash('success_msg');
    res.locals.error_msg = req.flash('error_msg');
    res.locals.error = req.flash('error');
    res.locals.user = req.user || null;
    next();
});

/**
 * routes used for redirecting the user
 */
const routesHTML = require('./modules/Routes').htmlRoutes(app);

/**
 * functionality of logging in
 */
const login = require("./modules/Login").login(app, connection);

/**
 * Require functionality to register and create an account
 */
const register = require('./modules/Register').register(app, connection);

登录模块

// require modeles here

module.exports.login = function (app, connection) {

passport.use(new LocalStrategy({
    usernameField: 'usernameOrEmail', // set default to usernameOrEmail because thats how it is called client side
},
    function (username, password, done) {

        var usernamePromise = User.checkUsername(connection, username);
        var emailPromise = User.checkEmail(connection, username);


        Promise.all([emailPromise, usernamePromise]).then(function (values) {

            // check if usernameOrEmail is known mail or known username
            if (!values[0] && !values[1]) {
                console.log("should thorw error message email unknown");;
                return done(null, false, { message: 'Unknown mail or username' }); // <-- does not show client side
            }

            // create promise to retrieve user from database
            var userPromise = User.getUserByUserNameOrEmail(connection, username);
            Promise.all([userPromise]).then(function (user) {

                // enctrypt password and compare
                bcrypt.compare(password, user[0].password, function (err, result) {
                    if (!!err) {
                        console.log("Error occured when comparing the decrypted passwords");

                        return done(err, false, { message: 'Error occured when comparing the decrypted passwords' });
                    }
                    else if (result) {
                        console.log("user succesfully logged in");
                        // Everything seems to be OK!
                        return done(null, user[0]);
                    }

                    else {
                        console.log("password is not correct");
                        return done(null, false, { message: 'Invalid password' });
                    }
                });
            });

        });
    })
);



passport.serializeUser(function (user, done) {
    done(null, user.id); 
});

passport.deserializeUser(function (id, done) {
    var userPromise = User.getUserById(connection, id);
    Promise.all([userPromise]).then(function (user) {
        if(user) {
            done(null, user);
        }
        else {
            done(null, false, { message: 'No user found with this user id' 
}); 
        }
});

app.post('/login',
    passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true }),
    function (req, res) {
        console.log("this code is reachable.."); // so far not executed yet
        res.redirect('/');
    });
}  // <-- closes the " module.exports.login = function (app, connection) { "

我的客户端正在使用.handlebars文件:

 {{#if success_msg}}
    <div class="alert alert-success">{{success_msg}}</div>
    {{/if}} 

    {{#if errors}} {{#each errors}}
    <div class="alert alert-danger">{{msg}}</div>
    {{/each}} {{/if}} 

[编辑] 经过一天的反复试验,我终于找到了一种刷新信息的方法:)

通过添加以下内容

通过本地策略中的要求:

passReqToCallback: true

这允许req.flash('error_msg','用户名或电子邮件未知'); 1

return done(null, false, req.flash('error_msg', 'Username or email not known'));

因为在server.js中,我拥有:

app.use(function (req, res, next) {
    res.locals.success_msg = req.flash('success_msg');
    res.locals.error_msg = req.flash('error_msg');
    res.locals.error = req.flash('error');
    res.locals.user = req.user || null;
    next();
});

“用户名或电子邮件未知”消息在浏览器中显示为客户端

{{#if error_msg}}
<div class="alert alert-danger">{{err_msg}}</div>
{{/if}} 

1 个答案:

答案 0 :(得分:1)

您的中间件集res.locals.error

res.locals.error = req.flash('error');

但是您的模板使用errors

{{#if errors}} {{#each errors}}
<div class="alert alert-danger">{{msg}}</div>
{{/each}} {{/if}} 

请注意,单数error和复数errors之间不匹配。

此外,我想知道{{msg}}是否不应该是{{this}}