2012-11-18 29 views
7

Tôi có thể kết nối ứng dụng Nút của mình với Redis tốt mà không cần mật khẩu, nhưng khi tôi thêm mật khẩu, không có gì tôi làm là đúng.Lỗi xác thực Redis với Node.js và socket.io

Dưới đây là mã của tôi ngay bây giờ, chân phải từ 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 chạy ứng dụng, tôi nhận được đống này dấu vết:

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

Dòng tạo này là trận chung kết một - nếu Tôi bình luận ra các nỗ lực để thiết lập RedisStore, tôi không nhận được bất kỳ lỗi nào.

Tôi chắc chắn mật khẩu là đúng (tôi có thể xác minh mật khẩu bằng redis-cli và nếu tôi thay đổi mật khẩu sai, tôi có thể xác minh rằng các cuộc gọi lại không kích hoạt). Mã này cũng hoạt động nếu tôi xóa mật khẩu và nhận xét hai dòng xác thực.

Tất cả các ví dụ hoạt động trên các bài đăng trên blog và tài liệu cũng như cho thấy điều này sẽ hiệu quả và tôi không biết tại sao tôi không làm như vậy. Tôi không biết phần nào của ngăn xếp cần xem.

Đây là những gì màn hình redis-cli trông giống như khi tôi chạy đoạn code trên:

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" 

Và đây là những gì màn hình redis-cli cho thấy nếu tôi tắt mật khẩu, nhận xét ra các dòng auth trên, và thành công chạy các ứng dụng:

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" 

các thành công (mật mã) kết nối làm cho 5 "info" lệnh, và không thành công (đặt mật khẩu) chỉ huy của tôi làm 2 - và sau đó chết trên một cuộc gọi đến một phương pháp "on_info_cmd".

Có ai có thể hiểu được điều này không? Thanks cho bất kỳ giúp bạn có thể cung cấp cho.

+0

Tôi đã giải quyết vấn đề này (trả lời bên dưới) và cập nhật plugin Socket.io để cung cấp ví dụ về RedisStore với ủy quyền: https://github.com/LearnBoost/socket.io/wiki/Configuring-Socket.IO – Konklone

Trả lời

9

Tôi đã giải quyết điều này bằng cách tự chuyển mô-đun redis làm tùy chọn cho hàm tạo RedisStore.

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

Điều này là cần thiết cho các đối tượng khách hàng vượt qua bài kiểm tra instanceof RedisClient và không được khởi tạo lại mà không có mật khẩu. Rõ ràng, khi RedisStore yêu cầu lại mô-đun redis, các ứng dụng khách redis được tạo bằng phương thức createClient là thành viên của một số lớp mới hoặc thứ gì đó.

Tôi đã tìm ra điều này bằng cách xem xét sự cố liên quan mà ai đó gặp phải trên số issue #808 của socket.io.

+0

Đã có lỗi khác nhau nhưng giải pháp tương tự đã giúp ... Có thể lỗi xảy ra vì Redis được sử dụng cho phiên Express quá và, có thể, các mô-đun khác nhau đã được sử dụng cho cửa hàng và cho khách hàng? – esp

1

Hãy thử gọi redisClient.auth(password, function (err) { if (err) throw err; }); chỉ một lần, redis lưu trữ thông tin xác thực cho mọi cuộc gọi, gọi điện thoại hai lần có thể gây ra lỗi.

+0

Nó thực sự chỉ được gọi một lần cho mỗi khách hàng - lần đầu tiên là trên redisClient, và thứ hai là trên redisSubscriber, một cá thể riêng biệt. – Konklone

+1

Có, tôi hiểu, nhưng khách hàng "stashes" mật khẩu, vì vậy bạn không cần phải gọi nó cho nhiều trường hợp. Vui lòng xem [Node_redis] (https://github.com/mranney/node_redis) và [Ví dụ Auth] (https://github.com/mranney/node_redis/blob/master/examples/auth.js) – Sdedelbrock

+1

Đó không phải đúng - nó stashes nó cho mỗi trường hợp, không phải cho cả lớp. Mỗi ví dụ auth tôi đã thấy của redis tạo ra một quán rượu, phụ, và một khách hàng cửa hàng sử dụng mô hình này. Ví dụ: https://github.com/LearnBoost/socket.io/pull/551 – Konklone

Các vấn đề liên quan