'how to set a new cookie without response object(express.js)

Before talking about issue, you need some background knowledge about my application.

I use node.js, express.js and mongoDB (with mongoose).
I was making a basic login function to do that I choose JWT for token and passport.js for authentication. and login flow is like below

  1. Issue access token(expires in 10mins) and refresh token (expires in 2 weeks)
  2. Store both token in cookies and store refresh token in DB too
  3. Make a strategy for authentication.
  4. Use strategy when you go to '/current' page.

Below is my code:

user.js:

router.post('/login', (req, res) => { 
    const { userid, password } = req.body;
    // find email
    User.findOne({ userid  })
        .then(user => {
            if (!user) {
                return res.json({
                    loginSuccess: false,
                    message: "Auth failed, ID not found"
                });
            }
            
            // compare password
            bcrypt.compare(password, user.password)
                .then(isMatch => {
                    if (isMatch) {
                        const accessPayload = {
                            id: user.id,
                            userid: user.userid,
                            role: user.role
                        };
                        // console.log(accessPayload.id);
                        const refreshPayload = {
                            id: user.id
                        }
                        jwt.sign(accessPayload, JWT_ACCESS_SECRET, { expiresIn:  JWT_ACCESS_EXPIRATION_TIME}, (err, token) => {
                            const accessToken = 'Bearer ' + token
                            const accessT = token
           
                            jwt.sign(refreshPayload, JWT_REFRESH_SECRET, { expiresIn: JWT_REFRESH_EXPIRATION_TIME }, (err, refreshT) => {
                                //note that maxAge is in milliseconds
                                res.cookie('accessToken', accessT, { httpOnly: true }) //secure: true
                                res.cookie('refreshToken', refreshT, { httpOnly: true })
                                res.json({
                                    success: true,
                                    refreshToken: 'Bearer ' + refreshT,
                                    accessToken: accessToken
                                })
                                User.saveRefreshToken(refreshT)
                                //이거 모듈화 왜앙돼
                            });
                        });
                    } else {
                        return res.json({ loginSuccess: false, message: "Wrong password" });
                    }
                });
        });
});
    
router.get('/current',passport.authenticate('custom', { session: false }), (req, res) => { 
    res.json({
        id: req.user.id,
        userid: req.user.userid,
        role: req.user.role
            
        // id: req.user.id,
    });
})'

and my strategy(custom) is like below

require('dotenv').config();
    
const { auth } = require('../middleware/auth');
const { append } = require('express/lib/response');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const passportCustom = require('passport-custom');
const CustomStrategy = passportCustom.Strategy;
// const res = require('express/lib/response');
const jwt = require('jsonwebtoken');
const mongoose = require('mongoose');
const User = mongoose.model('User');
    
const { verifyToken } = require('../utils/jwt');
    
module.exports = custom => {
    custom.use('custom', new CustomStrategy(
        function (req, done) {   
            const accessToken = req.cookies['accessToken'];
            const refreshToken = req.cookies['refreshToken'];
            //when both token are valid

            if (
                req && verifyToken('access', accessToken)
                && verifyToken('refresh', refreshToken)
            ) {  
                const verifyAccessToken = verifyToken('access', accessToken);

                const user = {
                    id: verifyAccessToken.id,
                    userid: verifyAccessToken.userid,
                    role: verifyAccessToken.role
                };
                    
                console.log(user)
                return done(null, user);
            }
            // when refresh token is valid but access token expired
            else if (
                req && !verifyToken('access', accessToken)
                && verifyToken('refresh', refreshToken)
            ) {
                console.log('you need new access token')
                const refreshTokenInfo = verifyToken('refresh', refreshToken);
                User.findById({ _id: refreshTokenInfo.id }, (err, user) => {
                    const Payload = {
                        id: user.id,
                        userid: user.userid,
                        role: user.role
                    }
                    console.log('old access token : ' +req.cookies['accessToken'])
                    jwt.sign(Payload, JWT_ACCESS_SECRET, { expiresIn: JWT_ACCESS_EXPIRATION_TIME }, (err, accessToken) => {
                        if (err) {
                            console.log(err)
                        }
                        console.log('new accesstoken : ' + accessToken)
                    });
                    return done(null, true)
                })
                return done(null, true)
            }
        }
    ))
}

The problem is at the case of ' // when refresh token is valid but access token expired'

When accessToken is expired but refresh one is valid I want to make new access token via information from DB(access DB when refresh token is correct) and set in cookie before done() However, I couldn't set cookie because there is no response object in parameter :/.
As far as I know, people use cookie to store access token and sometimes refresh it. I wonder how can I refresh my cookie in jwtStrategy and pass it to /current router so it recognize my refreshed access cookie

Thanks for reading, your help will be appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source