Search code examples
node.jsexpresspassport.js

Can't retrieve session id / cookies from passport.js login in order to send them with the next request


I am trying to login an user (by a .js file, not via postman or browser) and maintain the session throughout the code. The login function seems to work fine, passport.authenticate, passportConfig and serializeUser get called, the response status is 200 OK, but when I try to call a function like sendFunds, the response is 'User is not authenticated'.

It works if I post the requests via postman. It seems like the login request gets a cookie and sends it automatically with the sendFunds request.

I guess that I need to do the same in my accountGenerator.js file, that means call the login method, get the cookies and send them with the sendFunds request, but I can't figure it out. How do I get them and do I need to manually add them to the express-session ? Please :)

accountGenerator.js
async function loginUser(userLogin) {
    return post('http://localhost:3002/api/user/login', userLogin)
}

function sendFunds(transferDetails) {
    post('http://localhost:3002/api/user/sendFunds', transferDetails)
        .then((res) => {
            console.log(`Status: ${res.status}`);
        }).catch((err) => {
            console.error(err);
        });
}
const loginResponse = await loginUser(userLogin);
export function loginUser(req, res) {
    if (req.isAuthenticated()) {
        res.status(200).send({
            message: 'User is authenticated'
        });
        return;
    }

    passport.authenticate("local", {
        successRedirect: "/",
        failureRedirect: "/error"
        // failureRedirect: "/login"
    })(req, res, next);
}

export function sendFunds(req, res) {
    if (!req.isAuthenticated()) {
        res.status(401).send({
            message: 'User is not authenticated'
        });
        return;
    }

    req.body.secretKey = AUTHENTICATOR_SECRET_KEY;

    post(SEND_FUNDS_API_URL, req.body)
        .then((response) => {
            res.status(200).send(response.data);
        }).catch((err) => {
            console.error(err);
            res.status(500).send(err);
        });
}
export function passportConfig() {
    passport.use('local', new LocalStrategy(
        async (username, password, done) => {
            const response = await User.findOne({ name: username });
            if (!response) {
                return done(null, false, { message: 'Incorrect username.' });
            }
            const isValidPassword = await compare(password, response.password);
            if (!isValidPassword) {
                return done(null, false, { message: 'Incorrect password.' });
            }
            return done(null, response);
        }
    ))
}

passport.serializeUser((user, done) => {
    done(null, user.id)
})

passport.deserializeUser((id, done) => {
    User.findById(id, (err, user) => {
        done(err, user)
    })
})
app.use(expressSession({
    store: new MongoStore({
        mongoUrl: 'mongodb://127.0.0.1:27017/accountBankApp',
        // mongooseConnection: mongoose,
        ttl: 1 * 24 * 60 * 60, // = 365 days.
    }),
    secret: 'secret',
    resave: true,
    saveUninitialized: true,
}));

Solution

  • What worked for me was combining express-session with cookie-parser, even if cookie-parser is not required anymore in order for express-session to work.

    Since version 1.5.0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser.