2016-04-27 27 views
7

Sto utilizzando Express per le richieste proxy a un server API separato che è protetto dai token di accesso OAuth 2. Alla scadenza di un token, il server restituirà un 401 che sto gestendo nel middleware del router per poi andare a aggiornare il token di accesso associato alla sessione dei client (sto usando express-session).Richiamare nuovamente la stessa richiesta nel nodo express

Ecco il mio codice:

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!'); 
    } 
    }); 
}; 

Dopo aver aggiornato il token, vorrei ristampare la richiesta API originale che sto innescando utilizzando il modulo request nel mio controller recupero.

Sono un po 'perplesso sul modo in cui effettivamente faccio questo, c'è un modo elegante per raggiungere questo obiettivo?

risposta

0

Vorrei trasformare il controller di autenticazione da middleware in una promessa. Quindi effettuare ricorsive fetch.

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; 
};