Redis Cloud and connect-redis: the client is closed - node.js

I currently build a website using Express and want to use redis cloud database to save userID in session. The redisClient is created in redisClient.js and after that i pass it to redisStore in session in app.js. Here is the code:
redisCLient.js
const redis = require("redis");
let redisClient = redis.createClient({
host: process.env.REDIS_HOSTNAME,
port: parseInt(process.env.REDIS_PORT),
password: process.env.REDIS_PASSWORD
});
redisClient.on('error', function(err) {
console.log('*Redis Client Error: ' + err.message);
});
redisClient.on('connect', function(){
console.log('Connected to redis instance');
});
(async () => {
await redisClient.auth(process.env.REDIS_PASSWORD)
.catch(err => {console.log('Redis auth error: ' + err.message)});
await redisClient.connect()
.catch(err => {console.log('Redis connect error: ' + err.message)});
})();
module.exports = redisClient;
app.js
const session = require("express-session");
const redisStore = require('connect-redis')(session);
const redisClient = require('./session-store/redisClient');
...
app.use(cookieParser());
app.use(session({
store: new redisStore({client: redisClient, ttl: 3600 * 24 * 30}),
saveUninitialized: false,
secret: process.env.SESSION_SECRET,
resave: false
}));
The problem is: upon starting the server i got error messages log in console like this:
Redis auth error: The client is closed
*Redis Client Error: connect ECONNREFUSED 127.0.0.1:6379
*Redis Client Error: connect ECONNREFUSED 127.0.0.1:6379
*Redis Client Error: connect ECONNREFUSED 127.0.0.1:6379
*Redis Client Error: connect ECONNREFUSED 127.0.0.1:6379
...
I used this guide to set up redis cloud and assign dotenv variables (host, port and password). I have debugged and the dotenv is working fine and I have host, port and password variables correct.
But the problem still remains. I still get The client is closed and connect ECONNREFUSED 127.0.0.1:6379 error as in console log above. How can i fix this?

was stuck on same issue and found some luck. have used 'ioredis' module instead of redis which worked seamlessly.
const redis = require('ioredis');
const redisClient = redis.createClient({host:'your host address',port:your port,username:'',password:''});
redisClient.on('connect',() => {
console.log('connected to redis successfully!');
})
redisClient.on('error',(error) => {
console.log('Redis connection error :', error);
})
module.exports = redisClient;

When you create a client using redis.createClient, you need to use url instead of host, port.
refer to basic-example
it showing url format
redis[s]://[[username][:password]#][host][:port][/db-number]
in your case, it might be like this
var url = `redis://<YourUsername>:${process.env.REDIS_PASSWORD}#${process.env.REDIS_HOSTNAME}:${parseInt(process.env.REDIS_PORT)}`
redis.createClient({
url: url
});
Using host, port option must be the old version.

Option 1: switch the order of the calls to auth and connect
From the Node Redis client documentation:
When connecting to a Redis server that requires authentication, the AUTH command must be sent as the first command after connecting.
You should therefore switch the order of the calls to redisClient.auth and redisClient.connect.
Option 2: remove the call to auth
However, the documentation for the password property of createClient options states:
If set, client will run Redis auth command on connect.
As you are supplying password to createClient, you could alternatively just remove the explicit call to auth.

You must do await redisClient.connect() before you access the client. Try to move your redisClient.connect() just after you create it.

try this -->
var options = {
client: redis.createClient({
url : process.env.REDIS_URL,
legacyMode: true,
})};
you can make your url as 'redis://host:port'

import { createClient } from "redis";
const redisClient = createClient({
url: "redis://localhost:6379",
});
const start = async () => {
await redisClient.connect();
};
start();
export default redisClient;

Related

Connecting to redis using tls (ssl) and auth_token password in nodeJS

I am trying to connect to a redis instance in aws. I can connect to it using something like
redis-cli -h localhost -p 6379 -a <auth_token> --tls PING
However when I try this using node (redis library v4.2.0) doing something like this, it hangs
const redis = require("redis");
(async () => {
const client = redis.createClient( {
auth_pass:
"<auth_token>",
tls: { servername: "localhost", port: 6379 },
});
client.on("error", (err) => {
console.log("Redis Client Error", err);
});
client.connect();
console.log(await client.ping());
})();
Portforwarding is setup for redis in aws, which is why localhost is used.
The auth token is the same token I entered to the sparkleformation when redis was configured. both resting and transit encryption has been configured as well.
I have been trying to poke around on google for an answer, however there seem to be a lot of old documentation out there and none of the new ones are clear as to how to get a connection working using tls and an auth token. Any idea how to get this working?
If anybody is running into the same issue, I was able to get it working using ioredis instead.
const Redis = require("ioredis");
(async () => {
const redisRef = new Redis("rediss://:<auth_token>#localhost:6379");
console.log(await redisRef.ping());
})();
and setting this environment variable when running locally:
export NODE_TLS_REJECT_UNAUTHORIZED=0

Problems with migrating to Redis 4.x in Node

I am trying to migrate my google cloud app engine from Redis 3.x to 4.x. However, it appears that there have been some major changes in Redis 4.x. It appears that the client no longer autoconnect and there have been some chnages to the syntax. Here's what I have run
'use strict';
import {createClient} from 'redis';
// These are just values stored in environment variables.
const REDISHOST = process.env.REDIHOST;
const REDISPORT = process.env.REDIPORT;
const REDISAUTH = process.env.REDISAUTH;
const redisClient.createClient();
redisClient.host = REDISHOST;
redisClient.port = REDISPORT;
redisclient.auth = REDISAUTH;
redisClient.on('error', (err) => console.error(`##### REDIS ERR: ${err}.`));
await redisClient.connect();
I can tell that host, port, and auth is being set in redisClient, but when I connect, it tries to connect to localhost and fails. Any idea what I am missing here?
You need to pass the connection information in the call the createClient():
const redisClient = createClient({
socket: {
host: REDISHOST,
port: REDISPORT
},
password: REDISAUTH
})
There are lots of options for connecting. They are all detailed in the client configuration guide.

NodeJS to SQL Server Connection not working: socket hang up issue

Here is my complete code for sql connection, all code I have got from stackoverflow issues.
Everywhere, I found the same code is being suggested, hence I also tried with the same.
I have some other application which uses same connection with NextJs and it works fine, however, If I try only with NodeJS code, it gives some socket hang up error (code:'ESOCKET' name:'ConnectionError').
Please make a note that TCP is already configured on remote server and its working fine with other applications.
Any help is appreciated, thank you.
const express = require('express');
const fs = require('fs');
const path = require('path');
const cheerio = require("cheerio");
const sql = require('mssql');
require('dotenv').config(); //to use the env variables
// config for your database
var config = {
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
server: process.env.DATABASE_HOST,
database: process.env.SOMEDB,
port: 14345, // process.env.DATABASE_PORT,
options: {
encrypt: true, // for azure
trustServerCertificate: false // change to true for local dev / self-signed certs
}
};
// make sure that any items are correctly URL encoded in the connection string
let appPool = new sql.ConnectionPool(config);
//I got error on below connect
sql.connect(config).then(function(pool) {
//It never reaches here, it directly goes to the catch block
app.locals.db = pool;
const server = app.listen(3000, function () {
const host = server.address().address
const port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
}).catch(function(err) {
console.error('Error creating connection pool', err)
});
I have the same issue.
Try to use mssql version 6.0.1, it works on my code, but for sure we need to figure out the problem, since we can't think to mantain forever an old version of a package.
I kept trying to find the solution with different different configuration changes.
Finally, I have made a proper config, which worked and now its connecting properly as well as returning the data from the table.
require('dotenv').config(); //to access the process.env params
const sql = require("mssql"); //mssql object
var dbConfig = {
user: "ajay",
password: "abcd123",
server: "your_remote_sql_server_path",
port: 1433,
database: "your_database_name",
options: {
database: 'your_database_name',
trustServerCertificate: true
}
};
try {
//connection config will be used here to connect to the local/remote db
sql.connect(dbConfig)
.then(async function () {
// Function to retrieve the data from table
const result = await sql.query`select top 1 * from table_name`
console.dir(result)
}).catch(function (error) {
console.dir(error);
});
} catch (error) {
console.dir(error);
}
I am not sure what was the exact issue, but as per the previous config and this one, it seems like adding database name to the options has solved the issue.
Please make sure to save all the sensitive data to the .env file. (which you can access as PROCESS.env.parametername)
For me in driver mssql#9.1.1 making encrypt=false worked
const config = {
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
server: process.env.DATABASE_HOST,
database: process.env.SOMEDB,
port: 14345, // process.env.DATABASE_PORT,
options: {
encrypt: false
}
};

Not able to connect to heroku redis

const redis = require("redis");
let client = redis.createClient({
host: process.env.host,
port: process.env.port,
password:process.env.password
});
(async () => {
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
console.log("connected to redis")
})();
I have added redis-heroku addon to my project, Now I am trying to access it from my code but its giving me this error: "AuthError: ERR Client sent AUTH, but no password is set".
Also when I am trying to connect from terminal, I am able to connect to it but when I type any redis command , I get this "Error: Connection reset by peer".
If I am using this on my localsystem and local redis server its working fine
it will be helpful if anyone can provide me a working code of heroku redis, I think redis has two urls: REDIS_URL, REDIS_TLS_URL. The problem might be arising because of this tls(more secure)
Kinldy help me
Thanks
Heroku redis does not expose a host, port, and password variables. Instead they expose a REDIS_URL that contains all of those things in one string.
I believe you need to call createClient like this...
createClient({
url: process.env.REDIS_URL
});
In node-redis v4 the host and port should be inside a socket object, not directly on the main config object (see https://github.com/redis/node-redis/blob/master/docs/client-configuration.md):
const client = redis.createClient({
socket: {
host: process.env.host,
port: process.env.port
},
password: process.env.password
});

How to enable tls for heroku redis node?

I cannot connect to Heroku Redis using TLS. I tried whats given in heroku docs and the answer on this post How to Connect Heroku Redis TLS Node? but nothing seems to work. My current redis options look like:
const Redis = require('ioredis');
const url = process.env.REDIS_URL;
const options = {
tls: {
rejectUnauthorized: false,
},
};
const opts = new Redis(url, options);
Error that I am getting is
[ioredis] Unhandled error event:Error: connect ETIMEDOUT
at TLSSocket.<anonymous
(/app/node_modules/ioredis/built/redis/index.js:310:37)
at Object.onceWrapper (events.js:421:28)
at TLSSocket.emit (events.js:315:20)
.....
Also what is the difference between REDIS_URL and REDIS_TLS_URL? Which one to use?
REDIS_TLS_URL will have an extra 's' in the scheme of the url -> rediss://password#host:port vs. the REDIS_URL (with a single 's' in it's scheme). The other difference is the port. The TLS port is usually +1 of the regular port. On Heroku Redis version 6, you need to use the REDIS_TLS_URL along with tls option you defined above.
const Redis = require('ioredis');
const url = process.env.REDIS_TLS_URL;
const options = {
tls: {
rejectUnauthorized: false,
},
};
const opts = new Redis(url, options);

Resources