私人聊天(PHP + Socket.io)与PHP会话

我正在开发一个使用php + socket.io的私人消息系统的网站。

从一开始,我使用socket.emitsender_idrecipient_idtext传递给了socket.io,但后来才意识到这可能很容易被篡改,并希望以某种方式使用我的php会话,以确保sender_id确实是sender_id

我现在有下面的设置,但我真的不明白如何将会话从index.php传递到app.js,然后连接到app.js中的redis-server以获取保存user_id的PHPSESSID。

  • 运行nginx + php-fpm(index.php)的服务器1
  • 服务器2运行node.js与socket.io(app.js)
  • 运行redis进行会话pipe理的服务器3

我的代码现在看起来像下面,但显然缺less现在的Redis的一部分,我真的appriciate一些帮助。

谢谢!

的index.php

 <?php session_start(); if ($_SESSION['user_id'] == false){ header("Location:login.php");die; } ?> <script> var socket = io('https://app01.dev.domain.com:8895'); socket.on('connect', function(){ console.log("Connected to websockets"); }); socket.on('event', function(data){}); socket.on('disconnect', function(){}); $('.chat-message').keypress(function (e) { if (e.which == 13) { console.log("send message"); var friend_id = $(this).attr('id'); friend_id = friend_id.split("-"); friend_id = friend_id[3]; var obj = { recipient_id: friend_id, text: $(this).val() }; socket.emit('chat_message', obj); $(this).val(''); return false; } }); </script> 

app.js

 var https = require("https"), fs = require("fs"); var options = { key: fs.readFileSync('/etc/letsencrypt/live/domain/privkey.pem'), cert: fs.readFileSync('/etc/letsencrypt/live/domain/cert.pem'), ca: fs.readFileSync('/etc/letsencrypt/live/domain/chain.pem') }; var app = https.createServer(options); var io = require("socket.io")(app); var redis = require("redis"); // This i want to fill with for example PHPSESSION:user_id that i get from redis and later use it as sender // var all_clients = {}; io.set("transports", ["websocket", "polling"]); io.on("connection", function(client){ console.log("Client connected"); // Here i would like to connect to redis in some way and get the user_id but dont really understand how //all_clients[USER_ID_FROM_REDIS] = client.id; //var user_id = USER_ID_FROM_REDIS; client.on("chat_message", function(data){ var obj = { to: data.recipient_id, text: data.text }; console.log("Message inbound from socket: "+client.id+" from: "+data.user_id+" to: "+data.recipient_id+" with text: "+data.text); }); client.on("disconnect", function(){ console.log("Client disconnected "); //delete all_clients[USER_ID_FROM_REDIS]; }); }); app.listen(8895, function(){ console.log("listening on *:8895"); }); var recursive = function () { //console.log("Connected clients: "+Object.keys(all_clients).length); //console.log(JSON.stringify(all_clients)); setTimeout(recursive,2000); } recursive(); 

  1. HTTP本身并不能防止MITM攻击,为了防止MITM服务器证书需要被钉死。

  2. 为了防止用户被欺骗,您需要进行身份validation,例如login或像Dropbox这样的秘密令牌。

  3. 添加证书locking,这只是行话来validation您连接到正确的服务器,而不是validation由服务器发送的证书的MITM。 MITM过去比较困难,但是WiFi让Hot Sports很容易连接到错误的terminal,即使在家里我也看到了。