node.js - 在 Node express 中再次调用相同的请求

标签 node.js express middleware node-request

我正在使用 Express 将请求代理到一个单独的 API 服务器,该服务器受 OAuth 2 访问 token 保护。当 token 过期时,服务器将返回一个 401,我现在正在我的路由器中间件中处理它,然后去刷新与客户端 session 关联的访问 token (我正在使用 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!');
    }
  });
};

更新 token 后,我想重新发出我在获取 Controller 中使用 request 模块触发的原始​​ API 请求。

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

最佳答案

我会把授权 Controller 从中间件变成一个 promise 。然后使 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;
};

关于node.js - 在 Node express 中再次调用相同的请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36883413/

相关文章:

node.js - 环回异步/等待 UnhandledPromiseRejectionWarning 问题

node.js - Node/巴别塔 : Switching from babel-node or babel-register to babel-cli for production

node.js - Mongoose - 如何将模式中间件接入 'init' 事件?

java - Camel 过滤器方法签名

node.js - 如何限制用户只能访问Loopback中的组元素?

node.js - Google 数据存储无法在 Docker 内部连接

node.js - sequelize.js - 如何从 sequelize 生成的查询中删除双引号

python - 尝试从python-shell获取数据,将其解析为nodeJS中的对象

node.js - nodejs firebase 错误 RangeError : Maximum call stack size exceeded failure

node.js - 构建的 TypeScript 应用程序从错误的 src 而不是 dist、文件夹导入