2017-08-08 86 views
1

我正在開發一個使用php + socket.io的私人消息系統的網站。使用PHP會話進行私聊(PHP + Socket.io)

從我通過sender_idrecipient_idtext使用socket.emit到socket.io但後來意識到,這可能是與很容易篡改,想用我的PHP會議以某種方式,以確保年初的sender_id的確是sender_id

我現在有下面的設置,但我真的不明白如何將會話從index.php傳遞到app.js,然後連接到app.js中的redis-server以獲取保存user_id的PHPSESSID。

  • 服務器1個運行的nginx + PHP-FPM(的index.php)
  • 服務器2週上運行的node.js與socket.io(app.js)
  • 服務器3運行redis的會話管理

我的代碼現在看起來像下面,但顯然缺少現在的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(); 
+0

你需要什麼樣的安全級別?什麼是[威脅模型](https://www.tripwire.com/state-of-security/security-data-protection/threat-modeling-10-common-traps-you-dont-want-to-fall-爲/)。 – zaph

+0

@zaph我不會發送像密碼或類似的東西這樣的關鍵數據到socket.io,但我想確保數據不會被篡改。稍後,redis服務器將在生產中被隔離。 – sparkey

+0

@zaph Dont真的不知道這意味着什麼恐懼:(像JWT的東西? – sparkey

回答

1
  1. HTTP本身並不能防止MITM攻擊,以防止MITM服務器證書需要被釘死。

  2. 爲防止用戶被欺騙,您需要身份驗證,如登錄或像Dropbox這樣的祕密令牌。

  3. 添加證書鎖定,這只是行話,用於驗證您是否通過驗證服務器發送的證書來連接到正確的服務器而不是MITM。 MITM過去比較困難,但WiFi讓Hot Sports很容易連接到錯誤的終端,即使在家裏我也看到了這一點。