KOBA789です。 クライアント側で document.cookie を使って Cookie を取得するのはセキュリティ上の理由で非推奨です。セッション情報の Cookie は原則 HttpOnly にすべきです。 Socket.IO のコネクションにセッション情報を渡す安全な方法は、Node のサーバーを PHP 側と同じドメインで動くようにして、Socket.IO のハンドシェイク HTTP リクエストのヘッダから Cookie を読むことです。
以上、重箱の隅をつつくようですみませんが、よりセキュアなアプリケーションを構築するためのお役に立てればと思います。 On Aug 3, 2013 1:39 AM, "Takayuki Yamaguchi" <takayuki.yamaguc...@gmail.com> wrote: > 永田さん > > こんにちは。山口です。 > > CoffeeScriptですが、簡単なサンプルを記載します。 > > > 1.セッション共有化のフェーズ > ■クライアント(ブラウザ)側のJS > socket = io.connect "http://example.com:3000" > socket.on 'connect', => > socket.emit('cookie', { cookie: document.cookie }) > #Websocketの接続できたらCookieを送る > > ■Node > http = require('http') > cookie = require('cookie') > querystring = require('querystring') > > sockets = {} > io = require('socket.io').listen(3000) > io.sockets.on 'connection', (socket)-> > #クライアントからcookie送られてきた時の処理 > socket.on 'cookie', (data)-> > #Cookieをquerystringに変換 > user_cookie = cookie.parse(data.cookie).php_session_id > param = querystring.stringify({php_session_id: user_cookie}) > > #NodeJSからPHPに対してGETリクエストを飛ばしてPHPのUserIDを取得する > returnd_json = '' > req = http.request({ > host: "php.example.com" > port: 80 > path: '/backend/cookie' #PHP側のNode用認証API(Nodeにだけ公開しておく) > method: 'get' > headers: {'Cookie': param} #リクエストCookieにユーザーから受け取ったクッキーを渡す > }, (res)-> > res.setEncoding('utf-8') > res.on('data', (chunk)-> returnd_json += chunk ) > #sockets(適当に作ったオブジェクト)にPHP側のUserIDとsocketを紐付けて格納しておく > res.on('end', -> sockets[JSON.parse(returnd_json).user_id] = socket) > ) > req.end() > > ■PHP側( /backend/cookie ) > NodeからCookieが含まれたリクエストを送られるので、 > PHP的にはNodeのリクエストもユーザーのリクエストも、 > 同一のセッションと見なされるとおもいます。 > フレームワークによってはUser-Agentなども見てると思うので、 > その辺はフレームワークにあわせてNode側からのHTTPリクエストの内容を改変してください。 > > なので、PHP側は単純にUserIDを含んだJSONを返します。 > > return json_encode(array('user_id' => $user_id)); > > ------------- > 超適当ですが、大体こんな感じで、「Websocket」のセッションに対して、 > PHP側のUserIDなどをひもづける事が可能かと思います。 > > 注意点としてはCookieがHTTP onlyだとJSから取得送信できないので、 > その場合この手法は使えません。 > > > 2. PHP,Node間のデータやりとりフェーズ > RedisのPub/Subを使う場合の例です。 > ■Node > redis = require('redis') > pubsub = redis.createClient() > pubsub.subscribe('notice') #notice チャンネルをsubscribeしておきます > pubsub.on('message', (channel, data_string)-> #PHPから来たら配信します > data = JSON.parse(data_string) > for user_id in data.user_ids #PHPから渡された対象ユーザーにだけemitします > sockets[user_id].emmit('notice', {message: data.message}) > > ■PHP > $redis->publish('notice', json_encode(array( > 'user_ids' => $target_user_ids, > 'message' => $message, > ))); > > ■クライアントJS > socket.on 'notice', (data)-> > alert(data.message) > > 以上です。動かしてないのでタイポってたらすみません。 > > > expressフレームワークを利用することが前提で記載されております。 > > 基本的には利用する方が望ましいでしょうか。 > > どの程度の事をやりたいかによるのかと思いますが、 > 上記のサンプル程度のメッセージのやりとりだけであれば、 > 特に不要かと思います。 > > 参考になれば幸いです。よろしくお願いします。 > > ================================== > 山口 貴之 (ヤマグチ タカユキ) > email: takayuki.yamaguc...@gmail.com > twitter: https://twitter.com/takyam > blog: http://new.takyam.com/ > ================================== > > > 2013年8月2日 22:27 永田真也 <nagata.shi...@lancers.co.jp>: > > 山口様 > > > > お世話になります。 > > 永田です。 > > > > この場合のセッションの扱いなのですが、以下の認識で合っていますでしょうか。 > > > > 1.セッション共有化のフェーズ > > 1-1.PHPサイトにログインしたユーザAのHTTPセッションと > > NodeのWebsocketセッションをユーザIDをキーとして共有化する。 > > 1-2.PHPサイトにログインしたユーザBのHTTPセッションと > > NodeのWebsocketセッションを ユーザIDをキーとして共有化する。 > > 2. PHP,Node間のデータやりとりフェーズ > > ユーザAからユーザBに通知したい場合、 > > ユーザAのアクションのタイミングでNodeにリクエストを投げる。 > > このときに通知先のユーザBのIDを渡し、 > > それをキーにしてPUSH配信する。 > > > > また、教えて頂いた参考サイトや過去投稿を見ても、 > > expressフレームワークを利用することが前提で記載されております。 > > 基本的には利用する方が望ましいでしょうか。 > > > > 申し訳ございませんが、ご回答頂ければ幸いです。 > > よろしくお願いいたします。 > > > > > > 2013年8月2日金曜日 0時33分34秒 UTC+9 takyam: > >> > >> はじめまして。山口と申します。 > >> > >> 私もPHPのWAFで殆どの機能を構築しPUSH通知のところだけNodeを利用する構成を以前模索したことがあります。 > >> > >> その時は一応動作するところまでいけましたので簡単に説明します。 > >> > >> 手元にPCがないので概略になりますがご了承ください。 > >> > >> 例えばPHPのアプリケーションがログイン機構を持っていて、 > >> (例えばFacebookのように)ユーザー毎に通知を出し分けたいような場合です。 > >> > >> まずNodeが持つWebsocketのセッションとPHP側で持つHTTPのセッションを共有化します。 > >> > >> http://d.hatena.ne.jp/sugyan/touch/20110406/1302090071 > >> > >> 上記のすぎゃーんさんの記事を参考にしつつ、phpのアプリ側のセッションIDが入ったcookieをnodeになげて、 > >> nodeからphpのアプリに投げて、 > >> node側で、websocketのセッションとPHP側のセッション情報、 > >> 例えばログインユーザーIDなどを紐付けます。 > >> > >> 後は、PHPからNodeに対してHTTPリクエストないし、 > >> RedisのPubSubを使うなどして、 > >> 任意のタイミングでPUSHしたい対象ユーザーの一覧と、PUSHしたいJSONデータなどを渡します。 > >> > >> > >> > Node側では、そのPHPからのリクエストを元に、必要なデータを必要なユーザーに対して、Socket.IO経由でデータを送る事でPUSH通知が実現できます。 > >> > >> セッション共有化の部分とその後のPHP,node間のデータやりとりのフォーマットだけ決めてしまえば、Node側は100行程度で完結し、 > >> 以後nodeのメンテは必要ないのがメリットです。 > >> > >> これだけだと分かりにくいかと思いますが、ご参考になれば幸いです。 > >> > >> @takyam > >> > >> 2013/08/01 23:27 "永田真也" <shin....@gmail.com>: > >>> > >>> はじめまして。 > >>> 永田と申します。 > >>> > >>> Node.js+Socket.IOで通知機能を開発中です。 > >>> Node.jsでHTTPサーバを立ててPUSH通知の送受信ができることは確認しておりますが、 > >>> 既存のPHPサイトがあり、 > >>> Node.jsでのPUSH通知機能を埋め込みたいのですが、 > >>> どういった方法で実現可能かご教示頂けば幸いです。 > >>> iframeを使う、Socket.IOのポーリングプロトコルを使う > >>> などを考えていますが、他に良案はありますでしょうか。 > >>> よろしくお願いいたします。 > >>> -- > >>> > >>> --- > >>> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。 > >>> このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscr...@googlegroups.com > >>> にメールを送信します。 > >>> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。 > >>> > >>> > > > > -- > > > > --- > > このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。 > > このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscr...@googlegroups.comにメールを送信します。 > > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。 > > > > > > -- > > --- > このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。 > このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscr...@googlegroups.comにメールを送信します。 > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。 > > > -- --- このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。 このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscr...@googlegroups.com にメールを送信します。 その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。