2012-11-18 13 views
7

Ich kann meine Node App mit Redis ganz gut ohne ein Passwort verbinden, aber wenn ich ein Passwort hinzufügen, ist nichts, was ich tue, richtig.Redis Auth Fehler mit Node.js und socket.io

meinen Code Hier ist gerade jetzt, gerade von an example genommen:

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 })); 

im App ausgeführt wird, erhalte ich diese 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) 

Die Linie zu erzeugen dies die letzte ist - wenn Ich habe den Versuch, den RedisStore einzustellen, auskommentiert, ich bekomme keine Fehler.

Ich bin sicher, dass das Passwort richtig ist (ich kann es in redis-cli überprüfen, und wenn ich das Passwort falsch ändere, kann ich überprüfen, dass die Auth-Callbacks nicht ausgelöst werden). Dieser Code funktioniert auch, wenn ich das Passwort entferne und die beiden Auth-Zeilen auskommentiere.

Alle Arbeitsbeispiele auf Blog-Posts und Dokumente und dergleichen zeigen, dass dies funktionieren sollte, und ich weiß nicht, warum meine es nicht ist. Ich weiß nicht, welchen Teil des Stapels ich betrachten soll.

Hier ist, was der redis-cli Monitor aussieht, wenn ich den Code oben ausgeführt:

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" 

Und hier ist es, was redis-cli-Monitor zeigt an, ob ich das Passwort zu deaktivieren, über die Auth-Linien auf Kommentar, und erfolgreich die App laufen:

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" 

die erfolgreiche (passwordless) Verbindung macht 5 „Info“ Befehle und mein nicht erfolgreich (passworded) Befehl macht 2 - und dann stirbt bei einem Aufruf zu einem „on_info_cmd“ -Methode.

Kann jemand Sinn machen? Danke für jede Hilfe, die Sie geben können.

+0

Ich löste dies (Antwort unten), und aktualisiert das Socket.io Wiki, um ein Beispiel für RedisStore mit Autorisierung zu bieten: https://github.com/LearnBoost/socket.io/wiki/Configuring-Socket.IO – Konklone

Antwort

9

Ich löste dies, indem ich das redis-Modul selbst als eine Option an den RedisStore-Konstruktor übergab.

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

Dies war notwendig, dass die Client-Objekte den instanceof RedisClient Test bestehen und nicht ohne Passwort neu initialisiert werden. Offensichtlich, wenn RedisStore das redis-Modul erneut erfordert, sind redis-Clients, die mit der createClient-Methode erstellt wurden, Mitglieder einer neuen Klasse oder etwas.

Ich habe das herausgefunden, indem ich ein verwandtes Problem betrachtete, das jemand auf socket.io's issue #808 hatte.

+0

Hatte einen anderen Fehler, aber die gleiche Lösung half ... Wahrscheinlich ist ein Fehler passiert, weil Redis auch für Express-Sitzungen verwendet wird, und vielleicht wurde das andere Modul für den Speicher und für den Client verwendet? – esp

1

Versuchen Sie einmal, redisClient.auth(password, function (err) { if (err) throw err; }); nur einmal anzurufen, speichert die Auth-Information für jeden Anruf erneut, das zweimal aufrufen kann einen Fehler verursachen.

+0

Es wird für jeden Client nur einmal aufgerufen - das erste Mal ist auf redisClient und das zweite Mal auf redisSubscriber, eine separate Instanz. – Konklone

+1

Ja, ich verstehe, aber der Client "stashed" das Passwort, so dass Sie es nicht für mehrere Instanzen aufrufen müssen. Bitte schauen Sie sich [Node_redis] (https://github.com/mranny/node_redis) und [Auth Beispiel] an (https://github.com/mranny/node_redis/blob/master/examples/auth.js) – Sdedelbrock

+1

Das ist nicht richtig - es staut es pro Instanz, nicht für die ganze Klasse. Jedes Auth-Beispiel, das ich bei redis gesehen habe, erstellt einen Pub, Sub, und ein Store-Client verwendet dieses Muster. Beispiel: https://github.com/LearnBoost/socket.io/pull/551 – Konklone

Verwandte Themen