Skip to content

node.js x react x Auth0 Error: connect ECONNREFUSED 127.0.0.1:80 when using docker-compose but not when using docker run #297

@NoeJuzaAltis

Description

@NoeJuzaAltis

Description

Provide a clear and concise description of the issue, including what you expected to happen.

I'm using a React front end (served by my node.js back end) to make secured requests to my express-jwt secured backend (see code samples below).
Everything worked fine in the development and tests phases (using node alone and simple docker runs).
But when I started using docker-compose to deploy my whole stack (I have redis,mongo and influx containers that need to interact with maximum security, easy and fast configuration customization hence the use of docker-compose) everything went wrong and I couldn't make any secured requests to my back end as it was trowing 500s!
It says it wants (but fails) to connect to "127.0.0.1:80", my web app (and its container) is running on port 8080 and I never call anything remotely similar to the localhost on port 80 anywhere (not in front end nor back end).

Expected behavior: Secure api request with valid token returns the datas to the authorized user as it does with node standalone and docker run.
Current behavior: With docker-compose access to front end and unprotected routes is possible and works great but access to express-jwt protected routes throws error (see log sample below).

Since the issue is appearing only for express-jwt routes I'm pretty sure the issue comes from this lib and/or one of its components.

Reproduction

Detail the steps taken to reproduce this error, what was expected, and whether this issue can be reproduced consistently or if it is intermittent.

The issue happens consistently every time I run my web container with docker-compose. but not when I run it with a simple docker run
Steps to reproduce:

  1. deploy an express-jwt protected api with docker-compose
  2. try to access a protected route

Where applicable, please include:

  • Code sample to reproduce the issue

Back end code sample

import path from 'path';
import express from 'express';
import expressStaticGzip from "express-static-gzip";
import cors from 'cors';
import dotenv from 'dotenv';
import jwt from 'express-jwt';
import jwks from 'jwks-rsa';

const app = express(); // defining an instance of express lib in the object "app"
dotenv.config() // getting environement variables from ".env" or the real envs of the system
const __dirname = path.resolve();

function shouldCompress (req, res) {
  if (req.headers['x-no-compression']) {
    // don't compress responses with this request header
    return false
  }

  // fallback to standard filter function
  return compression.filter(req, res)
}

var jwtCheck = jwt({ // Creating authentication validator as described by Auth0's Doc.
    secret: jwks.expressJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 1000,
        jwksUri: process.env.JWKSURI
  }),
  audience: process.env.AUDIENCE,
  issuer: process.env.ISSUER,
  algorithms: [process.env.ALGORITHMS]
});
app.use(cors());
app.use(compression({ filter: shouldCompress }));

//-------------------------------------------------------------------------------------------------------------------------------------------------
// secured API endpoint example
app.route("/api/secure/v1/test")
.get(jwtCheck, (err,req) =>{
    res.status(200).send({"status":"working lol"})
})
app.use(function (err, req, res, next) {    // adding error handling to the express server to prevent it from "crashing" when someone tries to query secured API without a token.
    console.log("passing through error handling middleware")
    if (err) {
        console.log("there was an error. Error: ", err)
        if(err.status == 401)    // if error is token not found
        {
            console.log("secured access attempted with no or an invalid auth token provided. Provided token:", req.headers.authorization )
            res.status(401).redirect("/errors?code=401") // send error to front with status 401 Unauthorized
        }else{
            res.status(err.status).send("error %d", err.status)
        }
    }else{
        next();
    }
});
app.use("/", expressStaticGzip(path.join(__dirname,"client","build"), {enableBrotli: true, index: false}));
app.get("*", (req, res) => {
    //console.log("passed through front end routing")
    res.sendFile(path.join(__dirname,'client' , 'build', 'index.html'));
});
// make the webserver listen on port 8080
console.log("static content served from: " + path.join(__dirname, 'client', 'build', 'static') )
app.listen(8080, () => console.log('API and front are running on http://localhost:8080/'));

Dockerfile for web service

FROM node:16

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

COPY client ./client

RUN npm run build
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "run", "start" ]

docker-compose web service description:

web:
    restart: unless-stopped
    image: registry.gitlab.com/someprivateImage
    expose:
      - 8080
    ports:
      - "8080:8080"
    links:
      - "cache:cache"
    depends_on:
      - api
      - cache
    environment:
      - PORT=8080
      - DOMAIN="example.com"
      - CLIENTID="example"
      - JWKSURI="example.com/jwks.json"
      - AUDIENCE="example.com/api"
      - ISSUER="example.com"
      - ALGORITHMS="RS256"
      - REDISHOST=cache
      - REDISPORT=6379
    networks:
      - tpi-noejuza-net
  • Log files (redact/remove sensitive information)

logs when trying to access secured endpoint:

passing through error handling middleware
there was an error. Error:  Error: connect ECONNREFUSED 127.0.0.1:80
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1157:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 80
}

Environment

Please provide the following:

  • Version of this library used: "express-jwt": "^6.1.1"
  • Version of the platform or framework used, if applicable: node v16.15.0
  • Other relevant versions (language, server software, OS, browser): Manjaro Linux x86_64 kernel : 5.15.41-1-MANJARO
  • Other modules/plugins/libraries that might be involved:(see import section of code sample)+ Docker Compose version 2.5.1 Docker version 20.10.16

Thank you all in advance for your precious help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions