Попытка закодировать аутентификацию пользователя для входа в экспресс, не удается войти в систему с использованием экспресс-сеанса в узле

Я пытаюсь написать код для аутентификации пользователя при входе в экспресс с использованием экспресс-сеанса.

Это мой account.js API

.use(bodyParser.urlencoded())
.use(bodyParser.json())
.use(session({ secret: 'hcdjnxcds6cebs73ebd7e3bdb7db73e' }))
.get('/login', function (req, res) {
    res.sendfile('public/login.html');
})
.post('/login', function (req, res) {
        var user = {
            username : req.body.username,
            password : hash(req.body.password)
        };
        var collection = db.get('users');
        collection.findOne (user, function (err, data) {
            if (data) {
                req.session.userId = data._id;
                res.redirect('/');
            } else {
                res.redirect('/login');
            }
        });
})
.get('/logout', function (req, res) {
        req.session.userId = null;

        res.redirect('/');
})
.use(function (req, res, next) {
        if (req.session.userId) {
            var collection = db.get('users');
            collection.findOne({ _id : new ObjectId(req.session.userId)}, function (err, data) {
                req.user = data;
            });
        }
        next();
});

модуль.экспорт = маршрутизатор;

А это мой код server.js

var express = require('express'),
    api         = require('./api'),
    users       = require('./accounts'),
    app         = express();

app
    .use(express.static('./public'))
    .use('/api', api)
    .use(users)
    .get('*', function (req, res) {
            if (!req.user) {
                res.redirect('/login');
            } else {
                res.sendfile(__dirname + '/public/main.html');
            }
    })
    .listen(3000);

Моя проблема в том, что в server.js req.user получает нулевое значение, поэтому я не могу войти в систему. Но в account.js req.user получает пользовательские данные, которые не отражаются в server.js.

Опять же, если в accounts.js я помещаю next() внутрь оператора if (req.session.userId), я могу чтобы получить пользовательские данные в server.js, но это создает проблему при выходе из системы.

Пожалуйста, помогите мне в этом.


person rajat    schedule 29.04.2015    source источник


Ответы (1)


Ваш accounts.js выполняет next() до того, как ваш запрос коллекции вернется, поэтому имеет смысл, что ваш req.user не определен в вашем промежуточном программном обеспечении позже. Чтобы исправить это, попробуйте следующее:

.use(function (req, res, next) {
        if (req.session.userId) {
            var collection = db.get('users');
            collection.findOne({ _id : new ObjectId(req.session.userId)}, function (err, data) {
                req.user = data;
                next();
            });
        } else {
            next();
        }
});

В качестве примечания, вы очень сильно заново изобретаете колесо, реализуя вход пользователя самостоятельно. Я бы порекомендовал взглянуть на passportjs для такого входа пользователя в систему.

person Andrew Lavers    schedule 29.04.2015
comment
эй @andrew, я попробовал твое предложение, теперь он отправляет запрос на сервер и остается в ожидании ... навсегда - person rajat; 30.04.2015
comment
эй @andrew, спасибо, все готово. Я забыл добавить еще один следующий внутри if(). Работает в настоящее время. И я обязательно загляну в паспорт тоже - person rajat; 30.04.2015
comment
Следуя замечанию о повторном изобретении колеса, я бы посоветовал вам проверить размещенное решение для управления пользователями, такое как Stormpath. : Я там работаю. У нас отличная экспресс-интеграция. - person robertjd; 07.05.2015