Search code examples
expresscookiesjwt

Header sent error express.js with cookie-parser


I am build backend server. I use express.js, jsonwebtoken and cookie-parser for user authentication. I define middleware functions:

const protect = catchAsync(async (req, res, next) => {
  // 1) Getting token and check of it's there
  let token;
  if (req.cookies.jwt) {
    token = req.cookies.jwt;
  }
if (!token) {
    return next(
      new AppError('You are not logged in! Please log in to get access.', 401)
    );
  }
  const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);
  const currentUser = await Users.findByPk(decoded.id);
  if (!currentUser) {
    return next(
      new AppError(
        'The user belonging to this token does no longer exist.',
        401
      )
    );
  }

  req.user = currentUser.toJSON();

  return next();
});

After I do restrictTo :

const restrictTo = async (req, res, next) => {
  const { permissions } = req.user.role;
  permissions.forEach((element) => {
    const { method, path, name } = element;
    if (req.method.toLowerCase() === method.toLowerCase()) {
      const ok = checkUrl(req.originalUrl, path);
      if (ok) {
        console.log('gedo');
        return next();
      }
    }
  });
  return next(new AppError('you dont have permission', 403));
};

Here I simple define route: router.route('/').get(protect, restrictTo, getAllCountry); I get response successfully. But when see console.log I see this error:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:405:5)

How can I fix this?


Solution

  • I just looked your code and it seems like you made a small mistake in your restrictTo function. You used a forEach loop and return next(); is executed again after the response has already been sent. To fix this, you can use a flag variable and if the flag has correct value, return next(); is executed.

    I provide updated code:

    const restrictTo = (req, res, next) => {
      const { permissions } = req.user.role;
      
      let isRightPermission = false;
    
      permissions.forEach((element) => {
        const { method, path, name } = element;
        if (req.method.toLowerCase() === method.toLowerCase()) {
          const ok = checkUrl(req.originalUrl, path);
          if (ok) {
            isRightPermission = true;
          }
        }
      });
    
      if (isRightPermission) {
        return next();
      }
    
      return next(new AppError('You don’t have permission', 403));
    };