2012-01-06 14 views
14

私は小さなマルチプレイヤーゲームに取り組んでいます。私は認証を導入したいと思います。私はNode.jsとSocket.ioを使用しています。socket.ioソケット確立後の認証

メインページが到着したとき - ログインしているかどうかに関わらずゲームに参加してもらいたいが、誰でもその中で何もできない(時計のみ)。

どうすれば、すでに開いているソケットでユーザーを認証することができますか?

私がサイトを離れて戻っても認証を維持できますか?あなたはウェブソケットを通してクッキーを渡すことができますか?私の質問を促進するために

EDIT

。考えられる考えのひとつは、websocket接続を提供することです。ログインしようとすると、ユーザ名とパスワードがwebsocketにメッセージとして渡されます。

client.on('onLogin', loginfunction); 

私は、そのセッションは、そのユーザーに認証されていると言って、ソケットのセッションIDを取得し、どこかにそれを渡し、データベースに対してチェックし、ユーザー名とパスワードを取ることができます。

これは安全ですか?ソケットにクッキーを実装して戻ってくることができますか? socket.ioには、受信した各メッセージを手動でチェックするのではなく、ソケットが認証されたことを示す方法がありますか?

乾杯

+0

を?ユーザーは、既存の接続の準備ができたらログインの詳細を提供し、サーバーは一意のセッションIDを検証して返すことができます。クライアント側のjavascriptは、将来の使用のためにクッキーを保存することができます。 –

+0

socket.ioセッションを認証する方法については、[この記事(http://www.danielbaulig.de/socket-ioexpress/)]を参照してください。 – fent

+0

はい、実際に記事を読んでいます。クッキーを設定するのはとても幸せですが、ソケットがすでに開いている場合、同じページにログインすることはできません。おそらく、ユーザーがクッキーを無効にしている場合は、おそらく苦しんでいますか? –

答えて

5

これはあまりにもハード、実際にはありませんが、あなたはそれを間違った方法に近づいています。カップルの事:

  1. あなたははsocket.ioでクッキーを設定することはできません。ただし、接続しているクライアントのCookie値はいつでも取得できます。クッキーを設定するには、新しいHTTPレスポンスを送信する必要があります。つまり、ユーザーは最初に新しいhttpリクエストを送信する必要があります(リフレッシュするか新しいページに移動する必要はありません)。

  2. はい:socket.ioは安全です(送信されるデータがある限り)。このように

、次の操作を実行できます、ユーザーの初期接続で

なエクスプレスのセッションミドルウェアから生成されたものとして、固有のセッションIDとクッキーを作成します。セッションの終了時に有効期限が切れるように設定する必要があります(そうしないと、ブラウザを閉じるとすぐに期限が切れます)。

次に、CookieセッションIDを格納するオブジェクトを作成する必要があります。新しいconnect.sid Cookieが設定されるたびに、新しいオブジェクトにデフォルト値false(ユーザーはセッションで認証されたが、ログオンでは認証されていないことを意味します)を格納します。

ユーザーのログイン時に、サーバーに送信します。次に、ログイン資格情報を認証し、その後、作成したセッションIDオブジェクトを更新して、現在のソケットIDに対して真(ログイン済み)にします。

新しいhttp要求を受け取ったら、cookie.sidを読み取り、オブジェクト内の値が真であるかどうかを確認します。

それは次のようになります。おそらく、接続が確立され、完全なハンドシェイクされた後socket.io以内に認証されたような接続を設定する方法はあり

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

私が間違っている場合は私を修正しますが、期限切れのないセッションは一般的に安全でないとみなされます。 – brthornbury

+0

@Mozoby私のコードでは、一定の時間が経過した後にクッキーが期限切れになるよう設定しています。元の質問では、返されたユーザーはまだログインしている必要があると思われたため、既定で行ったようにブラウザが終了するまでCookieを期限切れにすることはできません。 – Ari

2

クリス、私はsocket.ioの専門家ではないので、お答えすることはできません私は、私は多分あなたを助けることができる別の方向にあなたを指すように試みることができる - といくつかの開発時間を取り除く。

しかし、まず免責事項:私はRealtime.coに勤務しており、何らかの宣伝をしようとしていません。私は開発者と緊密に協力しています。問題解決のためのすぐれたソリューションを提供することで、お客様のお手伝いをしています。また、ゲーマーであるため、人々がゲームを楽しむのを手助けしようとしているのです。

Realtimeは、チャネルにユーザーの読み取り/書き込みアクセス許可を与えることができる認証/認可レイヤーを使用します。ユーザーがWebサイトにアクセスすると、ゲームチャネルに読み取り専用のアクセス許可を与え、ログインすると書き込み許可を与えることができます。これは、認証ポストを実行してサーバーに再接続することで簡単に実行できます(すべてクライアント側で行うことができます)。しかし、セキュリティを強化するためにサーバー側でやっています。

RealtimeにはNode.js APIがあり、サーバーと簡単に統合できます。他の多くのプラットフォーム(モバイルを含む)用のAPIもあり、同じように動作するので、チャネルを完全に制御しながらゲームを同じ通信レイヤーで複数のプラットフォームで動作させることができます。

読んでいただきありがとうございます。

編集:あなたはより多くの情報のためにここにドキュメントを読むことができます

http://docs.xrtml.org/

関連する問題