2012-01-06 11 views
14

Tôi đang làm việc trên một trò chơi nhiều người chơi nhỏ. Tôi muốn giới thiệu xác thực. Tôi đang sử dụng Node.js và Socket.io.xác thực socket.io sau khi thiết lập socket

Khi người dùng đến trang chính - tôi muốn họ tham gia trò chơi cho dù họ có đăng nhập hay không - nhưng họ sẽ không thể làm bất cứ điều gì trong đó (chỉ xem).

Làm cách nào để tôi có thể xác thực người dùng trên ổ cắm đã mở?

Tôi có thể duy trì xác thực nếu họ rời khỏi trang web và quay lại không? Bạn có thể chuyển cookie qua ổ cắm web không?

EDIT

Tiếp tục câu hỏi của tôi. Một trong những suy nghĩ có thể tôi có là cung cấp kết nối websocket, sau đó khi họ cố gắng đăng nhập, nó sẽ chuyển tên người dùng và mật khẩu dưới dạng tin nhắn tới websocket.

client.on('onLogin', loginfunction); 

tôi sau đó có thể kéo dài tên người dùng và mật khẩu, kiểm tra đối với cơ sở dữ liệu, sau đó lấy ID phiên họp của ổ cắm và vượt qua nó ở đâu đó nói rằng phiên được xác thực để người dùng đó.

Tính năng này có an toàn không? Tôi vẫn có thể triển khai cookie trên ổ cắm để họ có thể quay lại không? Có cách nào trong socket.io nói rằng ổ cắm bây giờ được xác thực thay vì kiểm tra thủ công trên mỗi tin nhắn nhận được?

Cheers

+0

Có cách nào có thể thiết lập các kết nối như chứng thực trong vòng socket.io sau khi kết nối đã được thiết lập và bắt tay hoàn chỉnh? Người dùng có thể cung cấp chi tiết đăng nhập khi sẵn sàng kết nối hiện có, máy chủ có thể xác thực và trả lại một ID phiên duy nhất. JavaScript phía máy khách sau đó có thể lưu cookie để sử dụng trong tương lai. –

+0

Xem [bài viết này] (http://www.danielbaulig.de/socket-ioexpress/) về cách xác thực phiên socket.io. – fent

+0

Có, tôi đã thực sự đọc bài viết đó rồi. Trong khi tôi khá hạnh phúc khi thiết lập một cookie, nó không cho phép đăng nhập trên cùng một trang nếu socket đã được mở. Nó cũng bị coi là có nếu người dùng có cookie bị vô hiệu hóa? –

Trả lời

5

Đây không phải là thực sự quá khó khăn, nhưng bạn đang tiếp cận nó một cách sai lầm.Một vài điều:

  1. Bạn không thể đặt cookie với socket.io; tuy nhiên, bạn có thể nhận được các giá trị cookie của bất kỳ khách hàng được kết nối nào vào bất kỳ lúc nào. Để thiết lập một cookie, bạn sẽ phải gửi một phản hồi http mới, có nghĩa là trước tiên người dùng phải gửi một yêu cầu http mới (còn gọi là refresh hoặc chuyển đến một trang mới, mà âm thanh đó không phải là khả năng cho bạn ở đây).

  2. Có: socket.io là an toàn (trong phạm vi mọi dữ liệu được truyền có thể).

Như vậy, bạn có thể làm như sau:

Mở kết nối ban đầu của người dùng, tạo ra một cookie với một ID phiên duy nhất, chẳng hạn như những người tạo ra từ phiên middleware Express. Bạn sẽ cần phải cấu hình những điều này không hết hạn vào cuối phiên mặc dù (nếu không nó sẽ hết hạn ngay khi họ đóng trình duyệt của họ).

Tiếp theo, bạn nên tạo một đối tượng để lưu trữ ID phiên cookie. Mỗi lần cookie connect.sid mới được đặt, lưu trữ trong đối tượng mới của bạn với giá trị mặc định là false (có nghĩa là người dùng đã được xác thực theo phiên, nhưng không phải bằng cách đăng nhập)

Khi đăng nhập của người dùng, hãy gửi một ổ cắm phát ra máy chủ, nơi bạn có thể xác thực thông tin xác thực đăng nhập và sau đó cập nhật đối tượng id phiên mà bạn đã tạo để đọc đúng (đã đăng nhập) cho id socket hiện tại.

Bây giờ, khi nhận được yêu cầu http mới, hãy đọc cookie.sid và kiểm tra xem giá trị của nó trong đối tượng của bạn có đúng không.

Nó sẽ giống như sau:

var express = require('express'), 
http = require('http'), 
cookie = require('cookie'); 

var app = express(); 
var server = http.createServer(app); 
var io = require('socket.io').listen(server); 


app.use(express.cookieParser()); 
app.use(express.session({ 
    secret: 'secret_pw', 
    store: sessionStore, 
    cookie: { 
     secure: true, 
     expires: new Date(Date.now() + 60 * 1000), //setting cookie to not expire on session end 
     maxAge: 60 * 1000, 
     key: 'connect.sid' 
    } 
})); 

var sessionobj = {}; //This is important; it will contain your connect.sid IDs. 

//io.set('authorization'...etc. here to authorize socket connection and ensure legitimacy 


app.get("/*", function(req, res, next){ 
    if(sessionobj[req.cookies['connect.sid']]){ 
     if(sessionobj[req.cookies['connect.sid']].login == true){ 
      //Authenticated AND Logged in 
     } 
     else{ 
      //authenticated but not logged in 
     } 
    } 
    else{ 
     //not authenticated 
    } 

}); 


io.sockets.on('connection', function(socket){ 
    sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].login = false; 
    sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].socketid = socket.id; 

    socket.on('login', function(data){ 
     //DB Call, where you authenticate login 
     //on callback (if login is successful): 
     sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid']] = true; 
    }); 

    socket.on('disconnect', function(data){ 
     //any cleanup actions you may want 
    }); 

}); 
+0

sửa tôi nếu tôi sai, nhưng không phải là phiên không bao giờ hết hạn thường được coi là không an toàn – brthornbury

+0

@Mozoby Mã của tôi đang đặt cookie hết hạn sau một khoảng thời gian nhất định đã trôi qua - nó không phải là vô thời hạn. Tôi đã làm như vậy bởi vì câu hỏi ban đầu dường như chỉ ra rằng người dùng cũ vẫn phải đăng nhập, điều đó có nghĩa là tôi không thể để cookie hết hạn trên trình duyệt gần giống như mặc định. – Ari

2

Chris, tôi sẽ không thể trả lời vì tôi không phải là một chuyên gia về socket.io, nhưng tôi có lẽ có thể thử để chỉ cho bạn hướng khác có thể giúp bạn - và lấy đi một số thời gian phát triển.

Nhưng trước tiên, tuyên bố từ chối trách nhiệm: Tôi làm việc cho Realtime.co và không cố gắng thực hiện bất kỳ loại quảng cáo nào. Tôi làm việc chặt chẽ với các nhà phát triển và tôi chỉ cố gắng giúp bạn bằng cách cung cấp cho bạn một giải pháp vượt trội cho vấn đề của bạn. Ngoài ra, là một game thủ, tôi không thể tránh xa việc cố gắng giúp mọi người chơi game của họ!

Thời gian thực sử dụng lớp xác thực/ủy quyền trong đó bạn có thể cung cấp quyền đọc/ghi của người dùng cho kênh. Khi người dùng truy cập vào trang web, bạn có thể cho họ chỉ đọc quyền truy cập vào kênh trò chơi và sau khi họ đăng nhập, bạn có thể cấp cho họ quyền ghi. Điều này có thể dễ dàng thực hiện bằng cách thực hiện một bài đăng xác thực và kết nối lại với máy chủ (tất cả có thể được thực hiện phía máy khách). Tôi sẽ làm điều đó phía máy chủ, tuy nhiên, để tăng cường an ninh.

Thời gian thực có API Node.js để bạn có thể dễ dàng tích hợp nó với máy chủ của mình. Vì nó cũng có API cho nhiều nền tảng khác (bao gồm cả di động) và tất cả đều hoạt động theo cùng một cách, bạn thực sự có thể làm cho trò chơi của bạn hoạt động trên nhiều nền tảng trên cùng một lớp giao tiếp, trong khi có toàn quyền kiểm soát các kênh.

Cảm ơn bạn đã đọc.

Edit:

Bạn có thể đọc tài liệu ở đây cho biết thêm: http://docs.xrtml.org/