skip to Main Content

I have a webapp deployed in azure, and I´ve also configured a azure redis cache, but I am not being able to make my cache work. My nextjs frontend app is hosted in vercel.

This is my redis client in my nodejs app:

const redis = require("redis");
const dotenv = require('dotenv');

dotenv.config({ path: './.env' });

// Variables de entorno para la caché
const cacheHostName = process.env.AZURE_CACHE_FOR_REDIS_HOST_NAME;
const cachePassword = process.env.AZURE_CACHE_FOR_REDIS_ACCESS_KEY;

if (!cacheHostName) throw new Error("AZURE_CACHE_FOR_REDIS_HOST_NAME is empty");
if (!cachePassword) throw new Error("AZURE_CACHE_FOR_REDIS_ACCESS_KEY is empty");

exports.connect = async () => {
  let client;

  if (process.env.NODE_ENV === 'production') {
    client = redis.createClient({
      // Configuración de Redis para TLS en producción
      url: `redis://${cachePassword}@${cacheHostName}:6380`,
      tls: {
        rejectUnauthorized: true // Asegúrate de que este valor sea verdadero para requerir SSL
      }
    });
  } else {
    // Configuración local de Redis para pruebas
    client = redis.createClient({
      host: 'localhost',
      port: 6379
    });
  }

  client.on('connect', () => {
    console.log('Cliente Redis conectado al servidor');
  });

  client.on('error', (err) => {
    console.error('El cliente Redis no pudo conectarse al servidor:', err);
  });

  client.on('end', () => {
    console.log('La conexión del cliente Redis se cerró');
  });

  await client.connect();

  return client;
};

My SSL port in the redis service is disabled and my SSL port is 6380, and the TLS version is 1.2

Everytime I make a request through postman or through my hosted app, the request stays in an infinite Sending request....

I have also tried with rejectUnauthorized: false and no changes were shown.

It seems that my redis client is connecting and failing connection in an inifinite loop:

Cliente Redis connected to the server
The Redis Client was not able to connect to the server: Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:218:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}
El cliente Redis no pudo conectarse al servidor: Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:218:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}
Cliente Redis connected to the server
The Redis Client was not able to connect to the server: Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:218:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}
The Redis Client was not able to connect to the server: Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:218:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}
Cliente Redis connected to the server

This is how I am handling redis in my controller method.

const { User } = require('../models');
const asyncHandler = require('../middlewares/async');
const { connect } = require('../redis/redis')

//@route    GET api/users/
//@desc     Get all users
//@access   Private
exports.getUsers = asyncHandler(async (req, res, next) => {
   const redis = await connect();

   const key = 'users';
   const redisUsers = await redis.get(key);

   if( redisUsers ) {
      console.log('Users From Redis')
      return res.status(200).json({
         success: true,
         data: JSON.parse(redisUsers)
      })
   }
      
   console.log('Users From DB')
   const users = await User.findAll();
   await redis.set(key, JSON.stringify(users));
   return res.status(200).json({
      success: true,
      data: users
   })
});

In my local environment if I connect to redis to port 6379 and to host localhost it works fine, but as soon as I try connecting to the service of redis in azure it fails.

In the network tab of the browser when I make a request going to a view that displays a list of users I get the request for long time with no status code and finally I get a CORS error but CORS is enabled from azure. Finally the response from my frontend is of type text/x-component instead of json.

Note: this error only occurs in requests that include redis in my server

2

Answers


  1. While trying your code and adding CORS in Azure, I encountered a CORS issue. We need to add CORS in your code using the CORS package in addition to the Azure CORS settings.
    To reslove the issues with SSL/TLS configuration and CORS, Follow these steps

    • Add the configuration settings for the TLS protocol in Azure Cache for Redis.

    • Add cors to the node js code as shown in the below sample code

    
    const  cors = require('cors');
    
    // CORS configuration
    
    const  corsOptions = {
    
    origin: "*",
    
    methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
    
    allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept"],
    
    };
    
    app.use(cors(corsOptions));
    
    
    

    I used this reference to Enable Transport Layer Security (TLS) Configuration in Azure Web app.

    enter image description here

    enter image description here

    enter image description here

    res.setHeader('Content-Type', 'application/json'); // Set the correct Content-Type header
    
    
    

    enter image description here

    Login or Signup to reply.
  2. The options on your call to .connect are incorrect. The host, port, and tls attributes need to be inside a socket property. This is a really easy mistake to make and I’ve done it myself several times.

    This is probably the cause of your error in production and while it’s not causing a problem for your local environment, it is still incorrect.

    The code should look like this:

    if (process.env.NODE_ENV === 'production') {
      client = redis.createClient({
        url: `redis://${cachePassword}@${cacheHostName}:6380`,
        socket: {
          tls: {
            rejectUnauthorized: true
          }
        }
      });
    } else {
      client = redis.createClient({
        socket: {
          host: 'localhost',
          port: 6379
        }
      });
    }
    

    Now, you might be wondering why the local case is working even though I am claiming it was configured incorrectly. That’s because localhost and 6379 are the default host and port for Redis. Node Redis looks for the socket.host and socket.port properties and if it doesn’t find them, it uses the defaults.

    This means that you could actually simplify the local code to just:

    client = redis.createClient();
    

    Either will work. And sometimes it’s better to be explicit rather than implicit. No judgment either way.

    If you run into similar things, the details on all the configuration options for Node Redis can be found in the client configuration guide on GitHub.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search