Passing and updating data along node-express app

Viewed 329

How can I pass and update data along node-express app without using DB.

So I am using passport to authenticate (consider this to be in src/google-passport.js),

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL:  process.env.GOOGLE_CALLBACK_URL,
    userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo',
    accessType: 'offline'
  }, (accessToken, refreshToken, params, profile, cb) => { 
        let profileSort = extractProfile(profile)
         mongooeHelperFunction.findUserByEmail(profileSort.email).then(response => {
           if (!response) {
            mongooeHelperFunction.createNewUser(profileSort)
            .then(res => {
               let newRes = {...res._doc}
                newRes["accessToken"] = accessToken
                cb(null, newRes)
            })
            .catch(error => {  throw error  })
           } else {
                let newRes = {...response._doc}
                newRes["accessToken"] = accessToken
                cb(null, newRes)
           }
        })
        .catch(error => {  throw error  })
    }
))

From Passport, I am getting an access token and refresh token. Usually Google access token is valid for an hour.

So I want to store the time when I receive my access token and If my access token is expired, I want to use a refresh token to get a new access token and then update the time after new access token is generated.

consider an api route

app.get("/something", isTokenValid, (req, res) => {

where isTokenValid is a middleware function and inside that function I could have when my passport token was created and then i could compare it with current time.

Aditionally if the token have expired, I have a function which would send the refresh token to get new access token and update the previous data/time of access token to the new date/time

Question: how can I pass and update data along node-express app

1 Answers

Create Context Object

As in your example, we add another middleware that creates context for middleware pipeline:

const initCtx = (req,res,next) => {
    req.ctx = {};
    next();
}

Then in your middleware declaration:

    app.get("/something", [initCtx, isTokenValid], (req, res) => {

Generally this could be done as first middleware in the pipeline, at top of your middleware declarations in whole app:

const initCtx = (req,res,next) => {
    req.ctx = {};
    next();
}
app.use(initCtx);

Passing Value into ctx

In isTokenValid middleware where you retrieving accessToken, and its expiration time, at end of it you can pass it through. Where access token expiration is tokenExpiration:

req.ctx.tokenExpiration = tokenExpiration;

Using value

In middleware that takes care of refreshing tokens :

 app.get("/something", [initCtx, isTokenValid], (req, res) => {
       const tokenExpiration = req.ctx.tokenExpiration; // you have token expiration time that you can compare and apply required logic in refreshing token middleware

Original Reply and Explanation

You can assign property ctx (context object) to express req object and pass through it information between middlewares. Then you will be able to check specific keys in this object in downstream middlewares and apply required logic.

ctx object could be created by first middlewares in the pipeline (this one often also checks requestId from headers and assigns it to ctx as well, so all actions within context of same request could be easily traced )

If token is valid you can assign req.ctx.tokenExpiration, and then in another middlewares check if there need to refresh it.

By the way Koa and Loopback frameworks work with ctx object out of the box.

Related