2012-11-18 85 views
7

我可以連接我的Node應用程序到Redis就好了沒有密碼,但是當我添加密碼時,我所做的一切都是正確的。Redis認證錯誤Node.js和socket.io

這裏的,現在我的代碼,從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 })); 

在運行的應用程序,我得到這個堆棧跟蹤:

/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) 

線產生這是最後一個 - 如果我評論了設置RedisStore的嘗試,我沒有遇到任何錯誤。我敢肯定,密碼是正確的(我可以在redis-cli中驗證它,如果我更改密碼是錯誤的,我可以驗證auth回調不會觸發)。如果我刪除密碼並註釋掉兩條認證行,此代碼也適用。

所有關於博客帖子和文檔等的示例都表明這應該起作用,我不知道爲什麼我的不是。我不知道要看哪個部分。

這裏是Redis的-CLI顯示器看起來,當我運行上面的代碼,如:

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" 

而且這裏是Redis的-CLI顯示屏中顯示,如果我關掉了密碼,註釋掉上面的AUTH行,成功運行應用程序:

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" 

成功(無密碼)連接,使5「信息」命令,我不成功(需要密碼)命令,使2 - 然後死在一個「on_info_cmd」方法的調用。

任何人都可以理解這一點嗎?謝謝你提供的所有幫助。

+0

我解決了這個問題(下面的答案),並更新了Socket.io wiki以提供授權的RedisStore示例:https://github.com/LearnBoost/socket.io/wiki/Configuring-Socket.IO – Konklone

回答

9

我通過將Redis模塊本身作爲選項傳遞給RedisStore構造函數來解決此問題。

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

這是必需的客戶端對象傳遞instanceof RedisClient測試和無需密碼不能被重新初始化。顯然,當RedisStore需要redis模塊時,使用createClient方法創建的redis客戶端是一些新類的成員。

我想通過查看某人在socket.io的issue #808上遇到的相關問題來解決這個問題。

+0

有不同的錯誤,但同樣的解決方案幫助...可能發生錯誤,因爲Redis也用於快速會話,也許,不同的模塊用於存儲和客戶端? – esp

1

嘗試僅呼叫redisClient.auth(password, function (err) { if (err) throw err; });一次,redis存儲每次調用的認證信息,調用它兩次可能會引發錯誤。

+0

It實際上每個客戶端只調用一次 - 第一次在redisClient上,第二次在redisSubscriber上,一個單獨的實例。 – Konklone

+1

是的我明白,但客戶端「存儲」密碼,所以你不需要爲多個實例調用它。請看[Node_redis](https://github.com/mranney/node_redis)和[Auth Example](https://github.com/mranney/node_redis/blob/master/examples/auth.js) – Sdedelbrock

+1

這不是正確 - 它存儲每個實例,而不是整個班級。我見過的每個創建一個pub,sub和store客戶端的auth例子都是使用這種模式。 示例:https://github.com/LearnBoost/socket.io/pull/551 – Konklone