Я пытаюсь настроить мое первое приложение js узла для входа в систему с использованием паспорта.Узел JS + Вход в паспорт
Итак, сначала первое. Я создаю файл /app/config/express.js
, чтобы настроить экспресс-материал. Так что мои app.js проще:
var app = require('./app/config/express')();
app.listen(3001, function(){
console.log("Servidor rodando");
});
Ok ... это круто. НО! Мой файл express.js слишком велик. Может быть, вы можете дать мне несколько советов о том, как реорганизовать это?
Я добавил несколько комментариев с некоторыми вопросами, которые я хотел бы сделать, чтобы этот код был лучше.
var express = require('express');
var load = require('express-load');
var expressValidator = require('express-validator');
var bodyParser = require('body-parser');
var passport = require('passport');
var Strategy = require('passport-local').Strategy;
var session = require('express-session');
var flash = require("connect-flash");
module.exports = function() {
// PLEASE READ 1
//
//
// Functions to organize code better.
// PS: if this functions are outside "module.exports", then Express
// doesnt 'inject' the 'app.infra' variable ....
// Is there a workaround to move these functions outta here?
//
//
function configureAuth(){
passport.use(new Strategy({
passReqToCallback : true
},
function(req, username, password, cb) {
var connection = app.infra.connectionFactory();
var userDao = new app.infra.dao.UserDao(connection);
userDao.login(username, password, function(err, user){
if (err) {
return cb(err);
}
if (!user) {
return cb(null, false);
}
return cb(null, user);
});
connection.end();
}));
//
//
// HERE IT IS!
//
//
passport.serializeUser(function(user, cb) {
cb(null, user.id);
});
passport.deserializeUser(function(id, cb) {
cb(null, user);
});
}
function configureExpressLibs(app){
app.set('view engine', 'ejs');
app.set('views','./app/views');
app.use('/static', express.static('./app/public'));
app.use(flash());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(expressValidator());
app.use(session({
secret: '086this 54is 23unkowned 67',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
}
function configureErrors(app){
app.use(function(err, req, res, next) {
console.error(err.stack)
next(err)
});
app.use(function(req,res,next){
res.status(404).render('errors/404');
next();
});
app.use(function(error, req,res,next){
res.status(500).render('errors/500');
next();
});
}
// PLEASE READ 2
//
//
// I've moved this to 'LoginController.js' in my routes folder but
// I didnt work... So I moved it here. Is there a work around?
//
//
function configureLoginRoutes(app){
function redirectToIndexIfLoggedIn(req, res, next) {
if (req.isAuthenticated())
res.redirect('/');
return next();
}
app.get('/login', redirectToIndexIfLoggedIn, function(req, res){
res.render('login/login');
});
app.post('/login', passport.authenticate('local', {
successRedirect : '/',
failureRedirect : '/login',
failureFlash : 'Invalid username or password.'
}));
app.get('/logout', function(req, res){
req.logout();
req.session.destroy();
res.redirect('/');
});
}
var app = express();
configureExpressLibs(app);
configureAuth();
configureLoginRoutes(app);
load('routes',{cwd: 'app'})
.then('infra')
.into(app);
configureErrors(app);
return app;
}
Таким образом, проблема сейчас, когда я войти в систему (это не имеет значения, если пользователь правильно или неправильно), я получаю:
Error: Failed to serialize user into session
Я гугле его и увидел причину этого потому что люди забыли реализовать «serializeUser». Но я сделал. Пожалуйста, ознакомьтесь с комментарием «ЗДЕСЬ ЭТО» по вышеуказанному коду.
Спасибо, ребята. Извините за большой код. Но я учусь и надеюсь, что с вашей помощью все будет лучше.
EDIT Мой десериализованный метод был неправильным. Я исправил его, используя:
passport.deserializeUser(function(id, cb) {
var connection = app.infra.connectionFactory();
var userDao = new app.infra.dao.UserDao(connection);
userDao.findById(id, function(err, user) {
done(err, user);
});
connection.end();
});
но приложение все еще не работает. Такая же ошибка.
EDIT РЕШЕНИЕ
Оказывается, моя реализация не так. Понимаете, mysql всегда возвращает массив. Таким образом, я исправил мой код так:
function(req, username, password, cb) {
var connection = app.infra.connectionFactory();
var userDao = new app.infra.dao.UserDao(connection);
userDao.login(username, password, function(err, user){
if (err) {
return cb(err);
}
if (!user) {
return cb(null, false);
}
// HERE
return cb(null, user[0]);
});
connection.end();
}));
И здесь:
passport.deserializeUser(function(id, cb) {
var connection = app.infra.connectionFactory();
var userDao = new app.infra.dao.UserDao(connection);
userDao.findById(id, function(err, user) {
// HERE
cb(err, user[0]);
});
connection.end();
});
}
Марко, вы проверили функцию serializeUser, я думаю, вы используете user.id, который не является их. Попробуйте распечатать его и проверить, имеет ли он значение – user3278897
Просто подсказка: в случае, если user.id равно 0, что является значением false-y в JavaScript, поэтому Passport считает, что вы не сериализовали своего пользователя. Я имею в виду, done (null, 0) // не сериализую пользователей на 0-й номер – user3278897
Спасибо пользователю :) Я проверил функцию сериализации. Он не определен, когда пользователь ошибается –