Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis auth error with Node.js and socket.io

I can connect my Node app to Redis just fine without a password, but when I add a password, nothing I do is right.

Here's my code right now, taken right from an example:

var redis = require('redis')
  , sio = require('socket.io')
  , RedisStore = sio.RedisStore
  , io = sio.listen();

var port = 6379
  , hostname = 'localhost'
  , password = 'password';

var redisClient = redis.createClient(port, hostname);
redisClient.auth(password, function (err) { if (err) throw err; });

var redisSubscriber = redis.createClient(port, hostname);
redisSubscriber.auth(password, function (err) { if (err) throw err; });

io.set('store', new RedisStore({ redisPub: redisClient, redisSub: redisSubscriber, redisClient: redisClient }));

On running the app, I get this stack trace:

/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:506
                throw callback_err;
                      ^
Error: Ready check failed: ERR operation not permitted
    at RedisClient.on_info_cmd (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:319:35)
    at Command.RedisClient.ready_check.send_anyway [as callback] (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:367:14)
    at RedisClient.return_error (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:502:25)
    at RedisReplyParser.RedisClient.init_parser (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:262:14)
    at RedisReplyParser.EventEmitter.emit (events.js:93:17)
    at RedisReplyParser.send_error (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:266:14)
    at RedisReplyParser.execute (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:125:22)
    at RedisClient.on_data (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:478:27)
    at Socket.<anonymous> (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:79:14)
    at Socket.EventEmitter.emit (events.js:93:17)

The line generating this is the final one - if I comment out the attempt to set the RedisStore, I do not get any errors.

I'm sure the password is right (I can verify it in redis-cli, and if I change the password to be wrong I can verify that the auth callbacks don't fire). This code also works if I remove the password and comment out the two auth lines.

All of the working examples on blog posts and docs and the like show that this should work, and I don't know why mine isn't. I don't know which part of the stack to look at.

Here's what the redis-cli monitor looks like when I run the code above:

1353227107.912512 [0 127.0.0.1:56759] "auth" "password"
1353227107.912719 [0 127.0.0.1:56758] "auth" "password"
1353227107.913470 [0 127.0.0.1:56759] "info"
1353227107.913639 [0 127.0.0.1:56758] "info"

And here's what redis-cli monitor shows if I turn off the password, comment out the auth lines above, and successfully run the app:

1353227252.401667 [0 127.0.0.1:56771] "info"
1353227252.402020 [0 127.0.0.1:56770] "info"
1353227252.402131 [0 127.0.0.1:56769] "info"
1353227252.402423 [0 127.0.0.1:56768] "info"
1353227252.402611 [0 127.0.0.1:56767] "info"
1353227252.406254 [0 127.0.0.1:56770] "subscribe" "handshake"
1353227252.406287 [0 127.0.0.1:56770] "subscribe" "connect"
1353227252.406314 [0 127.0.0.1:56770] "subscribe" "open"
1353227252.406321 [0 127.0.0.1:56770] "subscribe" "join"
1353227252.406326 [0 127.0.0.1:56770] "subscribe" "leave"
1353227252.406337 [0 127.0.0.1:56770] "subscribe" "close"
1353227252.406354 [0 127.0.0.1:56770] "subscribe" "dispatch"
1353227252.406372 [0 127.0.0.1:56770] "subscribe" "disconnect"

The successful (passwordless) connection makes 5 "info" commands, and my unsuccessful (passworded) command makes 2 - and then dies on a call to an "on_info_cmd" method.

Can anyone make sense of this? Thanks for any help you can give.

like image 383
Eric Mill Avatar asked Nov 18 '12 08:11

Eric Mill


People also ask

How do I use Redis with Node JS?

In order to use Redis with Node.js, you need to install a Node.js Redis client. The following sections demonstrate the use of ioredis, a community-recommended Redis client for Node.js with build-in support for promises. Another community-recommended client for Node.js developers is node_redis.

Which Redis client should I use for promises?

The following sections demonstrate the use of ioredis, a community-recommended Redis client for Node.js with build-in support for promises. Another community-recommended client for Node.js developers is node_redis. Additional Node.js clients for Redis can be found under the Node.js section of the Redis Clients page.

What is the socket Io Redis adapter used for?

We will use the socket.io-redis adapter provided by Socket.IO. This Redis server is used for its pub/sub functionality to coordinate events across multiple Socket.IO instances such as new sockets joining, exchanging messages, or disconnects.

What is socket Io in Node JS?

Socket.IO. A JavaScript library for real-time web applications that enables real-time, bi-directional communication between web clients and servers. Socket.IO has two components: a client-side library that runs in the browser, and a server-side library for Node.js. Both components have nearly identical APIs.


1 Answers

I solved this by passing the redis module itself as an option to the RedisStore constructor.

io.set('store', new RedisStore({redis: redis, redisPub: redisClient, redisSub: redisSubscriber, redisClient: redisClient }));

This was necessary for the client objects to pass the instanceof RedisClient test and not be re-initialized without a password. Apparently, when RedisStore re-requires the redis module, redis clients created with the createClient method are members of some new class or something.

I figured this out by looking at a related issue someone was having on socket.io's issue #808.

like image 54
Eric Mill Avatar answered Sep 28 '22 10:09

Eric Mill