Экспресс-сессия не может установить свойство user из неопределенного - PullRequest
1 голос
/ 21 июня 2019

Я пытаюсь войти в систему через почтальона , и каждый раз, когда я пытаюсь получить сообщение об ошибке

Невозможно установить свойство 'user' из неопределенного

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

adminController

exports.postAdminLogin = async (req, res, next) => {
    const userToFind = req.body.username,
        password = req.body.password;
    // Get data from the db that should be displayed  to user client
    try {
        const user = await User.findOne({username: userToFind});
        // If no user is found send 404 status and message
        if (!user) {
            return res.status(422).send('Invalid email or password');
        }
        // If a user is found compare password with the password passed from the request
        return bcrypt.compare(password, user.password)
        // If password matches
            .then(doMatch => {
                if (doMatch) {
                    req.session.isLoggedIn = true;
                    req.session.username = user.username;
                    res.session.user = user;
                    return req.session.save(err => {
                        if (err) {
                            console.log(`Error when trying to login with err ${err}`);
                        }
                        res.status(200);
                        next();
                    })
                }
            })
            // If bcrypt encounters an error
            .catch(err => {
                res.status(500).send(`This is the error ${err}`);
            });
        // If an error occurs when finding a user from the db
    } catch (err) {
        err ? res.status(500).send(err) : console.log('No user found')
    }
    next()
};

server.js

const path = require("path"),
    express = require("express"),
    app = express();
require('dotenv/config');

// imported dependencies
const bodyParser = require("body-parser"),
    mongoose = require("mongoose"),
    session = require('express-session'),
    MongoDBStore = require('connect-mongodb-session')(session),
    cors = require('cors'),
    log = console.log,
    User = require('./models/User');

    // Mongo Db Storage
const dbStorage = new MongoDBStore({
    uri: process.env.DATABASE_SESSION_URI,
    collection: 'sessions'
});

app.use((req, res, next) => {
    res.locals.isAuthenticated = req.session.isLoggedIn;
    next();
});

app.use((req, res, next) => {
    if (!req.session.user) {
        return next();
    }
    User.findById(req.session.user)
        .then(user => {
            if (!user) {
                return next();
            }
            req.user = user;
            next()
        })
        .catch(err => {
            next(new Error(err))
        });
});

// where to find routes
const adminRoutes = require("./routes/admin");
const menuRoutes = require("./routes/menu");

app.use((error, req, res, next) => {
    res.status(500);
    next();
});

// session config
app.use(require("express-session")({
    secret: process.env.DATABASE_SECRET,
    resave: false,
    saveUninitialized: false
}));

// points to static folder
app.use(express.static(path.join(__dirname, "public")));

// middleware
app.use(cors());
app.use(bodyParser.json());

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
    store: dbStorage
}));

app.use('/admin', adminRoutes);
// app.use('/menu', menuRoutes);

// production db
mongoose.connect(process.env.DATABASE_URL, {useNewUrlParser: true})
    .then(() => {
        log(`Connected to the database`);
        app.listen(process.env.SERVER_PORT, err => {
        err ? log(`Error occurred trying to connect to port: ${process.env.SERVER_PORT} with err code: ${err}`) : log(`Server connected on port: ${process.env.SERVER_PORT}`);
        });
    })
    .catch(err => {
        console.log(err)
    });

Я хочу, чтобы пользователь мог войти в систему и сохранить сеанс в БД

1 Ответ

0 голосов
/ 21 июня 2019

Вы инициализируете сессию дважды.Здесь:

app.use(require("express-session")({
    secret: process.env.DATABASE_SECRET,
    resave: false,
    saveUninitialized: false
}));

и здесь:

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
    store: dbStorage
}));

удалите один из них.

Затем вам нужно переместить инициализацию сеанса выше любого кода, который пытаетсяДоступ к сеансу.

Это первый раз, когда вы пытаетесь получить доступ к сеансу.

app.use((req, res, next) => {
    res.locals.isAuthenticated = req.session.isLoggedIn;
    next();
});

, поэтому вам нужно поместить инициализацию сеанса выше этого.

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
    store: dbStorage
}));

// now you can access session
app.use((req, res, next) => {
    res.locals.isAuthenticated = req.session.isLoggedIn;
    next();
});
...