我现在正在学习一些新技术(例如node.js,socket.io,redis等)并制作一些简单的测试应用程序,以了解它是如何工作的。
我的问题是关于客户端javascript代码的安全性:例如,我在node.js + express上有一个聊天服务器,当用户连接到这个聊天时,服务器应该分配他的注册用户名(通过oldschool授权) php + mysql用于他的套接字。问题是,用户是否可以修改其客户端脚本并连接到不同用户下的聊天内容。名字?
下面给出了一些代码:
(分配用户名的服务器端部分,即从客户端调用获取用户名)
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// store the username in the socket session for this client
socket.username = username;
// store the room name in the socket session for this client
socket.room = 'General';
// add the client's username to the global list
usernames[username] = username;
// send client to room 1
socket.join('General');
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected to General');
// echo to room 1 that a person has connected to their room
socket.broadcast.to('General').emit('updatechat', 'SERVER', username + ' has connected to this room');
socket.emit('updaterooms', rooms, 'General');
});
(将用户名发送到服务器的客户端部分,它看起来像' var username =" User&#34 ;;' for a specific user)
Yii::$app->view->registerJs('var username = "'.$user->identity->username.'";', yii\web\View::POS_HEAD);
(连接功能)
chat.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
chat.emit('adduser', username);
});
所以问题是:用户可以更改(例如,通过Chrome开发工具)他的用户名在线' var username ...'并以不同的名称连接聊天?
P.S。这种特殊情况只是一个例子,显然,聊天中的昵称改变只不过是一个简单的笑话,但类似的情况可能出现在其他项目中......
答案 0 :(得分:1)
假设您的变量在闭包中受到保护,并且通过在控制台中键入username='root'
来改变它们并非易事,用户可以简单地替换整个代码。
客户端发生的一切都完全不受您的控制。
好消息是它们是不涉及重复身份验证的解决方案。假设您已经在快速应用程序中对用户进行了身份验证,则可以从中获取会话和用户。
在我的chat server中了解我是如何做到的:
var sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
function die(err){
console.log('ERR', err);
socket.emit('error', err.toString());
socket.disconnect();
}
if (! (session && session.passport && session.passport.user && session.room)) return die ('invalid session');
var userId = session.passport.user;
if (!userId) return die('no authenticated user in session');
... handling socket for authenticated user
});
基本上,它使用session.socket.io module将会话从标准http请求(使用passport进行身份验证)传播到socket.io连接。并且应该由用户提供的所有内容都来自session / db / server。