Связанное промежуточное программное обеспечение приводит к зависанию экспресс-запроса - PullRequest
0 голосов
/ 01 октября 2018

Я следую примеру связывания промежуточного программного обеспечения из этого вопроса .

У меня есть маршрут app.put('/users/:id', isAuthenticated, (req, res) => {db.updateUser(req.params.id, req.body)}.Я пытаюсь написать функцию промежуточного программного обеспечения, которая проверяет, соответствует ли идентификатор, указанный в URL, идентификатору, полученному из JWT, включенного в запрос.

У меня уже есть функция isAuthenticated, которая проверяет JWT и устанавливает res.locals.userId к полученному UID;поэтому я хотел бы просто использовать это в этой новой функции canModifyTarget, но по какой-то причине запрос зависает навсегда:

// This function works fine

isAuthenticated: function(req, res, next) {
  let token;
  if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
    token = req.headers.authorization.split(' ')[1];
    admin.auth().verifyIdToken(token).then((decodedToken) => {
      res.locals.userId = decodedToken.uid;
      return next();
    }).catch((error) => {
      return res.status(HttpStatus.UNAUTHORIZED).send();
    })
  }
}

// Switching out isAuthenticated for this in the route causes a permanent hang

canModifyTarget: function(req, res, next) {
  console.log('This is printed');
  return (req, res, next) => {
    console.log('This is NOT printed');
    isAuthenticated(req, res, () => {
      if (req.params.id === res.locals.userId) {
        return next();
      }
      return res.status(HttpStatus.FORBIDDEN).send();
    })
  }
}

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Мне кажется, проще определить canModifyTarget как еще одно промежуточное ПО.Т.е.:

 function canModifyTarget(req, res, next) {
    console.log('This is NOT printed');
    if (req.params.id === res.locals.userId) {
     return next();
    }
    return res.status(HttpStatus.FORBIDDEN).send();
  }

, а затем просто примените его после isAuthenticated middleware:

app.put(
    '/users/:id',
    isAuthenticated,
    canModifyTarget,
   (req, res) => {db.updateUser(req.params.id, req.body)}
);

Надеюсь, это поможет.

0 голосов
/ 01 октября 2018
Промежуточные программы

должны быть функциями обратного вызова, которые вызывают "next ()" после завершения.Ваша первая функция, когда она выполняется, вызывает next () (в конце концов, после выполнения вашего обещания)

Ваша вторая функция не вызывает next (), она просто возвращает определение функции.

Определите это следующим образом

canModifyTarget: function(req, res, next) {
    isAuthenticated(req, res, () => {
      if (req.params.id === res.locals.userId) {
        return next();
      }
      return res.status(HttpStatus.FORBIDDEN).send();
    })
  }
}

, и если третий параметр isAuthenticated является обратным вызовом, он должен работать

Кроме того, вы должны определить случай "else" в вашем isAuthenticatedфункция, в противном случае она также будет зависать (может быть, генерировать исключение или что-то в этом роде?)

Если вам нужно ссылаться на них, храните их в переменных, а не непосредственно определяя их в вашем модуле.exports:

const isAuthenticated = function(req, res, next) {
// code here
}

const canModifyTarget: function(req, res, next) {
// code here
 }

module.exports = {
   isAuthenticated,
   canModifyTarget,
};
...