在node express中再次调用相同的请求

时间:2016-04-27 07:42:38

标签: node.js express middleware node-request

我使用Express将请求代理到受OAuth 2访问令牌保护的单独API服务器。当令牌过期时,服务器将返回我现在在路由器中间件中处理的401,然后刷新与客户端会话关联的访问令牌(我正在使用express-session)。

这是我的代码:

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

更新令牌后,我想重新发出我在fetch控制器中使用request模块触发的原始​​API请求。

我有点难过我实际上是怎么做的,有没有一种优雅的方法来实现这个目标?

1 个答案:

答案 0 :(得分:0)

我会将auth控制器从中间件转变为承诺。然后使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;
};