永遠不要相信客戶(存儲重要變量服務器端,而不是依賴於客戶端)
我會做一個簡單驗證(在能夠使用聊天之前選擇用戶名)協議。
const _onlineUsernames = {};
const MAX_USERNAME_LENGTH = 16;
io.on('connection', function(socket) {
//.: Login (Pick Username)
socket.on('enter',function(username){
if(username){ //did we really receive a username?
if(username.length!=0 && username.length<=MAX_USERNAME_LENGTH){
if(!_onlineUsernames[username]){
//username not in use, add to online list & verify :
_onlineUsernames[username] = {sid:socket.id};
socket.chat_verified = true; //used to verify username has been picked
socket.chat_username = username; //store in the socket
}else{socket.emit('error', 'username currently in use');}
}else{socket.emit('error', 'length of username supplied');}
}else{socket.emit('error', 'no username supplied');}
});
//.: Chat Logic
socket.on('chat message', function(msg) {
if(socket.chat_verified){ // Check if the user is verified (previously picked username)
console.log(socket.chat_username);
// Here, I would do some escaping/sanitation before emiting the message,
// mainly to prevent client-to-client injection (sanitation/escaping can be done in the client-side instead)
io.emit('chat message', msg);
}else{ socket.emit('error', 'chat_verification_required'); }
});
//.: Login (Pick Username)
socket.on('disconnect',function(){
// Check if disconnected user was verified (picked username)
if(socket.chat_verified){ delete _onlineUsernames[socket.chat_username]; }//username is free to be used again
});
});
客戶端將無法使用聊天,直到他們驗證的用戶名(插座「輸入」事件)
如果你擔心安全問題,你也應該消毒/逃脫的消息客戶。 示例:客戶端發送下面的消息(<script>alert('injected js!);</script>
)
編輯:(問題具體詢問從插座訪問會話)
使用express-session-socket.io中間件以暴露明示socket.io中的會話對象(類似於我在存儲用戶名的插槽中所做的操作)
代碼示例:簡單(你可能已經有了一個sessionStore自定義)
io.use(require('express-session-socket.io')(sessionStore, 'secret', function (err, session, socket, next) {
if (err) next(err);
socket.session = session;
next();
}));
來源
2017-08-03 18:00:30
EMX
https://github.com/christopheranderson/express-session-socket.io – robertklep