nils
nils

Reputation: 67

How to implement refresh token flow with Passport.js on Node.js backend?

As the title already says; I'm wondering how to implement the retrieval of a token in Passport.js.

Currently I have following strategy implemented:

passport.use(new GoogleStrategy({
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: '/api/auth/google/callback'
    },
    async (accessToken, refreshToken, profile, done) => {
        const newUser = {
            googleId: profile.id,
            displayName: profile.displayName,
            firstName: profile.name.givenName,
            lastName: profile.name.familyName,
            image: profile.photos[0].value,
            email: profile.emails[0].value
        };

        try {
            let user = await User.findOne({ googleId: profile.id });
            if(user) {
                done(null, user);
            } else {
                user = await User.create(newUser);
                await Key.create({
                    googleId: user.googleId,
                    keyProvider: 'Google',
                    token: accessToken,
                    refreshToken: refreshToken
                });
                done(null, user);
            }
        } catch (err) {
            console.error(err);   
        }
    }));

Now, for example, I want to call the Google API, lets say with this route:

router.get('/list', async (req, res) => {
   console.log('list called');

   const result = await axios({
       method: "GET",
       headers: {
           'Authorization': "Bearer [token which is stored in my db]",
       },
       "Content-Type": "application/json",
       url: 'https://www.googleapis.com/youtube/v3/subscriptions?channelId=[someid]',
   });
   console.log(result);
});

Where and how would I implement a function/middleware/module, that gets called every time I make a request to Google API, that retrieves a new accessToken on an error and then retries the call?

Since I'm fairly new to Node.js/Express I don't know how to put such a flow into code. The only option I'd know to implement is catching the error with axios and then manually retrieve a new accessToken with redundant code in every Google API endpoint.

Upvotes: 0

Views: 1725

Answers (1)

Gary Archer
Gary Archer

Reputation: 29218

I would say there are two main concepts here:

DESIGN PATTERN

It is standard to aim to retry 401s with a new access token, as you say - here is some axios code of mine.

AXIOS SPECIFICS

Axios has a comcept of interceptors and here is an example that does 401 retries.

PERSONAL PREFERENCES

Either is fine - I prefer my approach, which used to be called a service agent pattern. The important factors are:

  • Make business logic code that calls APIs nice and clean
  • Bear in mind that there are other cross cutting concerns that may need to be handled, so make room for that also

Upvotes: 1

Related Questions