2016-04-27 29 views
7

我正在使用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!'); 
    } 
    }); 
}; 

更新令牌后,我想重新问题,我用我取数据控制器的request模块触发原来的API请求。

我有点难住我该如何去做这件事,有没有一种优雅的方式来实现这一目标?

回答

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