Tengo una API de nodo que se implementa y ejecuta como una función Lambda dentro de AWS.
// mthd export const validateHeaderBearerToken = (req, res) => { if (!req.headers.authorization || req.headers.authorization.split(' ').length !== 2 || req.headers.authorization.split(' ')[0].trim() !== authConstants.BEARER_HEADER) { res.status(403) .send({ message: 'Invalid token' }); throw new AuthenticationException(authConstants.NO_VALID_TOKEN_IN_HEADER_ERROR); } return req.headers.authorization.split(' ')[1].trim(); };y el controlador
// controller searchApiV1Controller.use('/search/', checkAuthentication, searchRouter);el servicio principal
// mainService export const checkAuthentication = async (req, res, next) => { const bearerToken = req.headers.authorization; logger.info(`[${getCorrelationId(req)}] Authenticating the request`); const token = validateHeaderBearerToken(bearerToken, res); let application='liberty'; await checkAuthorize(application); ... }Cuando paso el token de portador vacío dentro del encabezado, debería responder el mensaje "Token no válido" con el código de estado 403. Pero dado que el servicio principal (middleware) es un método asíncrono, la llamada responde con el error 502 Bad Gateway debido a AuthenticationException. Si eliminamos esta excepción, responderá correctamente con 403. Pero el método de servicio principal se ejecutará de forma asincrónica a través de los otros métodos de subutilidad dentro del método checkAuthentication. Así que no podemos eliminarlo. ¿Cuál puede ser la solución para esto?
FYI: No tengo ningún problema mientras ejecuto localmente.
Cuando se usan cadenas de middleware en Express, normalmente es mejor usar la función next() que lanzar excepciones/errores. Los hace más componibles y también sigue el principio de no usar excepciones para controlar el flujo. Las excepciones son para circunstancias verdaderamente excepcionales, no para sus operaciones estándar.
Si pasa un valor a next() asumirá que es un error y saltará directamente a su middleware de manejo de errores. También puede agregar valores a res.locals para pasarlo a través de cadenas de middleware.
Por ejemplo:
export const validateHeaderBearerToken = (req, res, next) => { if (/* checks */) { return next(AuthenticationException(authConstants.NO_VALID_TOKEN_IN_HEADER_ERROR)); } res.locals.token = req.headers.authorization.split(' ')[1].trim(); }; Ahora, debido a que está configurando res.locals, no necesita llamar a su función de validación en checkAuthentication , puede usarla como middleware, convirtiendo esa función en algo como:
export const checkAuthentication = async (req, res, next) => { // Assume res.locals.token exists, otherwise we'll have early-exited the entire request. const bearerToken = res.locals.token let application='liberty'; let result = await checkAuthorize(application); // Example logic... if (result.is_authorised == false) { return next(/*error*/) } } Ahora nunca llamará a checkAuthentication si validateHeaderBearerToken no puede encontrar un token. La configuración de su enrutador se verá así:
searchApiV1Controller.use('/search/', validateHeaderBearerToken, checkAuthentication, searchRouter);Lectura adicional sobre el manejo de errores en express: http://expressjs.com/en/guide/error-handling.html