Search code examples
node.jsexpresssessionpassport.js

Cannot set headers after they are sent to the client Error while regenerating sessions


I'm facing with the "Cannot set headers after they are sent to the client" Error in Express/Passportjs. I do know that this error mainly occurs when callbacks has called twice, or more;, but I don't understand why this error has occured. I've specified Error cases on the bottom.

Here's the code that I've wrote in app.js for the strategy setup

passport.use(new KakaoStrategy(
{
    clientID: kakao_key,
    callbackURL: '/userSchemaAPI/login/kakao/callback',
},
async (accessToken, refreshToken, profile, done) => {
    try {
        const foundUser = await User.findOne(
            {
                snsId: profile.id,
                provider: 'kakao',
            },
        );
        if (foundUser) {
            return done(null, foundUser);
        }
        else{
            return done(null, false, profile);
        } 
    } catch (error) {
        return done(error);
    }
},
),

);

this is the router code

router.get('/login/kakao', passport.authenticate('kakao'));

router.get('/login/kakao/callback', (req, res, next) => {
    passport.authenticate('kakao', function (err, user, info){
        if (err) {
            return next(err);
        }
        if (!user) { 
            const { id } = info;
            req.session.joinUser = {
                snsId: id,
                email: info._json.kakao_account.email,
                username: info._json.properties.nickname,
            };
            return req.session.save(() => {
                res.redirect('/userSchemaAPI/register/kakao');
            });
        }
    return req.login(user, function (error){
        if (error) {
            return next(error);
        }
        return res.redirect('/');
    });
    })(req, res, next);
});

I try to register new user when user hasn't registered in our DB. here's the code when POST request has called in routes '/userSchemaAPI/register/kakao' -

module.exports.createNewKakaoUser = async(req,res,next)=>{
try {
    const { snsId, username, email } = req.session.joinUser;  
    const user = await User.create({
        provider : 'kakao',
        snsId : snsId,
        email: email,
        username: req.body.username || username,
    });
    req.session.regenerate(() => { 
        req.login(user, (error) => { 
            if (error) {
                return next(error);
            }
            return res.redirect('/');
        });
    });
} catch (error) {
    console.error(error);
    next(error);
}

}

There's 2 major Errors that I am currently facing with.

  1. I can't directly logIn when my info is already in DB.

  2. I succeeded to register my Info in DB, but server makes an "Cannot set headers after they are sent to the client" Error while logging in.


Solution

  • Your code will continue later after next is handled if you don't return

    req.session.regenerate(() => { 
        req.login(user, (error) => { 
            if (error) {
                return next(error);
            }
            return res.redirect('/');
        });
    });