2013-08-15 31 views
7

Tôi đang cố gắng xây dựng một ứng dụng trò chuyện dựa trên sails.js. Url cho các tin nhắn từ một cuộc trò chuyện cụ thể như sau:Cấp phép Sails.js cho các yêu cầu ổ cắm

/api/chat/:id/messages

Khi tôi yêu cầu url này với XHR, nó cung cấp một cookie phiên và sails.js xây dựng một đối tượng session. Tôi có thể dễ dàng kiểm tra quyền của người dùng để đọc tin nhắn từ cuộc trò chuyện cụ thể.

Tuy nhiên, tôi cần yêu cầu url này bằng socket.io để khách hàng có thể đăng ký tất cả các thay đổi trong tương lai của bộ sưu tập messages.

Khi tôi yêu cầu url này bằng socket.io, không có cookie phiên nào được đặt và phiên sails.js trống. Vì vậy, tôi không thể kiểm tra quyền của người dùng ở phía máy chủ.

Tôi hiểu rằng yêu cầu ổ cắm không phải là yêu cầu HTTP. Họ không tự cung cấp bất kỳ cookie nào.

Có cách giải quyết đơn giản nào không?

+0

Để làm rõ - bạn đang gặp phải vấn đề giữa nhiều miền, phải không? Như bạn đang nhúng một tập lệnh trên www.foo.com và mở một ổ cắm vào www.bar.com? – mikermcneil

+0

Không, Mike - đó không phải là vấn đề giữa nhiều miền. Cuối cùng tôi đã tìm thấy câu trả lời và đăng nó dưới đây. Bạn phải truy cập đối tượng phiên socket của bạn theo một cách khác. P.S. Có lẽ bạn nên triển khai giải pháp này vào lõi sails.js. – alevkon

Trả lời

5

Tôi tìm thấy cách để lấy đối tượng phiên được đặt trong khi bắt tay socket.io. Trong điều khiển của bạn, bạn nên làm một cái gì đó như thế này:

myControllerAction: function(req, res) { 
    var session = req.session; 
    if (req.isSocket) { 
     var handshake = req.socket.manager.handshaken[req.socket.id]; 
     if (handshake) { 
      session = handshake.session; 
     } 
    } 
    //session now contains proper session object 
} 

Bạn có thể thực hiện điều này trong chính sách sails.js, và đính kèm chính sách này đối với một số bộ điều khiển. Nhưng đừng viết phiên ổ cắm của bạn vào req.session! Nếu không, bạn sẽ gặp lỗi khi cố gắng trả lời ứng dụng (bản gốc req.session vẫn được sử dụng theo một cách nào đó). Thay vào đó, hãy lưu nó dưới dạng req.socketSession hoặc một cái gì đó tương tự.

3

vui lòng gửi yêu cầu JSONP từ ứng dụng của bạn trước khi gửi yêu cầu socket, điều này sẽ tạo cookie và chấp nhận yêu cầu ổ cắm.

+0

Điều này sẽ giúp ích như thế nào? Tôi đã có một cookie trước khi khởi tạo cái bắt tay socket.io. Tôi nên yêu cầu địa chỉ nào với JSONP? Tại sao JSONP, không phải là Ajax đơn giản? – alevkon

+0

bạn có thể dán lỗi của mình ở đây không? Là khách hàng và máy chủ của bạn có cùng tên miền, vui lòng cung cấp thêm chi tiết. –

+1

Câu trả lời này là phần còn lại của nhóm và tôi đã làm trong quá khứ-- để làm rõ, có vẻ như bạn đang làm ổ cắm giữa nhiều miền, phải không? Vấn đề là trình duyệt không gửi cookie khi thiết lập kết nối websocket. Thật không may, bạn có thể thấy rằng vẫn còn vấn đề trong Safari. @alevkon Bạn sẽ không thể sử dụng AJAX cơ bản vì nó là tên miền chéo - bạn sẽ cần sử dụng JSONP hoặc CORS (và CORS không được hỗ trợ đầy đủ mikermcneil

0

alevkon, trong phương pháp được đề cập ở trên, bạn phải thực hiện tương tự trong tất cả các trình điều khiển, vì bạn không biết bộ điều khiển nào được truy cập lần đầu tiên ... nhưng bằng cách gửi một yêu cầu jsonp, bạn có thể tạo cookie giữa máy khách và máy chủ, cùng một cookie được sử dụng cho đến phiên tiếp theo.

+1

Shiva, Nó không phải là vấn đề về cookie. Tôi có một số yêu cầu AJAX đã được gửi trước khi bắt tay socket, vì vậy cookie sails.sid đã được thiết lập. Vấn đề không phải về cookie, vấn đề là cách truy cập đối tượng phiên từ bộ điều khiển. nếu req.isSocket của bạn là đúng, bạn sẽ không tìm thấy phiên thích hợp trong đối tượng req.session của bạn, nhưng bạn vẫn có thể truy cập nó theo cách tôi mô tả. – alevkon

1

Bạn có thể thực hiện đăng nhập ban đầu của mình qua socket.post() thay vì XHR, các yêu cầu ổ cắm tiếp theo sẽ được ủy quyền.

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