Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling same request again in node express

I am using Express to proxy requests to a separate API server which is protected by OAuth 2 access tokens. When a token expires, the server will return a 401 which I am now handling in my router middleware to then go and refresh the access token associated with the clients session (I am using express-session).

Here is my code:

router.js

app.use('/api', require('./routes.js'));

routes.js

var express = require('express'),
  router = express.Router(),
  routesController = require('./routes.controller.js');

router.route('/*')
  .get(routesController.fetch);

routes.controller.js

module.exports.fetch = function(req, res, next) {
  var options = helpers.buildAPIRequestOptions(req);
  request(options, function(err, response, body){
    if(response.statusCode === 401) {
      authController.refreshToken(req, res, next);
    } else {
      res.status(response.statusCode).send(body);
    }
  });
};

authController

module.exports.refreshToken = function(req, res, next) {
  var formData = {
      grant_type: 'refresh_token',
      refresh_token: req.session.refreshToken,
      scope: 'PRODUCTION'
    },
    headers = {
      'Authorization' : 'Basic ' + consts.CLIENT_KEY_SECRET_BASE64_DEV
    };
  request.post({url:consts.ACCESS_TOKEN_REQUEST_URL_DEV, form:formData, headers: headers, rejectUnauthorized: false}, function(err, response, body){
    var responseBody = JSON.parse(body);
    if (response.statusCode === 200) {

      req.session.accessToken = responseBody.access_token;
      req.session.refreshToken = responseBody.refresh_token;
      next();
      //How to recall the original request made from fetch controller function after this point?
    } else {
      console.log('SOMETHING ELSE HAPPENED!');
    }
  });
};

After updating the token, I would like to re-issue the original API request that I am triggering using the request module in my fetch controller.

I'm a bit stumped how I actually go about doing this, is there an elegant way to achieve this?

like image 702
mindparse Avatar asked Apr 27 '16 07:04

mindparse


1 Answers

I would turn the auth controller from middleware into a promise. Then make fetch recursive.

routes.controller.js

module.exports.fetch = fetch;

function fetch(req, res, next) {
  var options = getSavedOptsFromRequest(req) || helpers.buildAPIRequestOptions(req);
  request(options, function(err, response, body){
    if(response.statusCode === 401) {
      saveOptsToRequest(req, options)
      authController.refreshToken(req)
      .then(function authOk(){
          fetch(req, res, next);
      })
      .catch(function authKo(){
          res.status(500).send('something');
      });
    } else {
      res.status(response.statusCode).send(body);
    }
  });
};

function saveOptsToRequest(req, options){
    req.requestedOptions = options;
}

function getSavedOptsFromRequest(req){
    return req.requestedOptions;
}

authController

module.exports.refreshToken = function(req) {
    var refreshTokenPromise = new Promise(function (resolve, reject){
        var formData = {
            grant_type: 'refresh_token',
            refresh_token: req.session.refreshToken,
            scope: 'PRODUCTION'
            },
            headers = {
            'Authorization' : 'Basic ' + consts.CLIENT_KEY_SECRET_BASE64_DEV
            };
        request.post({url:consts.ACCESS_TOKEN_REQUEST_URL_DEV, form:formData, headers: headers, rejectUnauthorized: false}, function(err, response, body){
            var responseBody = JSON.parse(body);
            if (response.statusCode === 200) {

            req.session.accessToken = responseBody.access_token;
            req.session.refreshToken = responseBody.refresh_token;
            resolve();
            //How to recall the original request made from fetch controller function after this point?
            } else {
            console.log('SOMETHING ELSE HAPPENED!');
            reject(new Error("Something!!!!"));
            }
        });
    });
    return refreshTokenPromise;
};
like image 123
Carlos Avatar answered Sep 20 '22 02:09

Carlos