2013-08-15 17 views
7

私はsails.jsに基づいてチャットアプリケーションを構築しようとしています。特定のチャットからのメッセージのURLは次のようになります。Sails.jsソケットリクエストの承認

/api/chat/:id/messages

私はXHRでこのURLを要求すると、それは、セッションクッキーを提供し、sails.jsは、セッションオブジェクトを構築します。私は簡単に特定のチャットからのメッセージを読むためにユーザーの権利を確認することができます。

しかし、クライアントがmessagesコレクションの今後の変更をすべて購読できるように、このURLにsocket.ioをリクエストする必要があります。

私はこのURLにsocket.ioを要求すると、セッションクッキーは設定されず、sails.jsセッションは空です。だから、私はサーバー側のユーザー権利を確認することはできません。

私はソケット要求がHTTP要求ではないことを理解しています。彼らは自分でクッキーを提供しません。

簡単な回避策はありますか?

+0

この問題を解決するには、クロスドメインが必要です。 www.foo.comにスクリプトを埋め込み、www.bar.comへのソケットを開くのと同じように? – mikermcneil

+0

いいえ、マイク - ドメイン間の問題ではありません。私は最終的に答えを見つけ出し、それを下に掲示しました。ソケットセッションオブジェクトに別の方法でアクセスする必要があります。 S.おそらく、この回避策をsails.jsコアに実装するべきでしょう。 – alevkon

答えて

5

socket.ioハンドシェイク中に設定されたセッションオブジェクトを取得する方法が見つかりました。

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 
} 

あなたはsails.jsポリシーでこれを実装し、いくつかのコントローラにこのポリシーを添付することができます:あなたのコントローラで は、あなたはこのような何かを行う必要があります。しかし、ソケットセッションをreq.sessionに書き込まないでください!そうしないと、クライアントに応答しようとするとエラーが発生します(元のreq.sessionは何らかの方法で使用されています)。代わりに、req.socketSessionなどのように保存してください。

3

ソケットリクエストを送信する前に、アプリケーションからJSONPリクエストを送信してください。これにより、Cookieが作成され、ソケットリクエストが受け入れられます。

+0

これはどのように役立ちますか?私はすでにsocket.ioのハンドシェイクを初期化する前にクッキーを持っています。 JSONPでどのようなアドレスを要求すればよいですか?単純なAjaxではなく、なぜJSONPですか? – alevkon

+0

ここにあなたのエラーを貼り付けることができますか?あなたのクライアントとサーバーは同じドメインにあります。 –

+1

この回答は、チームの残りの部分と私が過去に行ったことです。明確にするために、ソケットのクロスドメインを行っているようですね。問題は、ブラウザがwebsocket接続を確立したときにクッキーを送信しないことです。残念ながら、Safariにはまだ問題があることがあります。それはあなたがJSONPやCORSを使用する必要がありますクロスdomain--だからあなたが基本的なAJAXを使用することはできません@alevkon は (完全にサポートされていないとCORSを mikermcneil

0

alevkon上記の方法では、どのコントローラーに初めてアクセスするのかわからないので、すべてのコントローラーで同じものを実装する必要があります。ただ1つのjsonpリクエストを送信するだけで、クライアントとサーバー間のクッキーは、次のセッションまで同じクッキーが使用されます。

+1

シヴァ、それはクッキーの問題ではありません。私はいくつかのAJAX要求をソケットハンドシェイクの前にすでに送信しているので、sails.sidのクッキーはすでに設定されています。 クッキーに関する問題ではなく、問題はコントローラからセッションオブジェクトにアクセスする方法でした。 req.isSocketがtrueの場合、req.sessionオブジェクトでは適切なセッションが見つからないでしょうが、それでも説明した方法でアクセスできます。 – alevkon

1

XHRの代わりにsocket.post()を使用して初期ログインを行うことができます。その後のソケットリクエストは承認されます。