私もこの問題に直面しました。これは、スパムが発する限り、私の解決策でした(悪意のあるソケットの使用)..
var spamData = new Object();
var spamCheckFunctions = ["updateUsers","moreEmits"]; // anti-spam will check these socket emits
var antiSpam = 3000; // anti spam check per milliseconds
var antiSpamRemove = 3; // -spam points per antiSpam check
var maxSpam = 9; // Max spam points before disconnect is thrown to the socket
io.sockets.on('connection', function (socket) {
// Spam Check, this binds to all emits
var emit = socket.emit;
socket.emit = function() {
data = Array.prototype.slice.call(arguments);
if(spamCheckFunctions.contains(data[0])){
addSpam(socket);
};
emit.apply(socket, arguments);
};
var $emit = socket.$emit;
socket.$emit = function() {
data = Array.prototype.slice.call(arguments);
if(spamCheckFunctions.contains(data[0])){
addSpam(socket);
}
$emit.apply(socket, arguments);
};
});
function maxSpamCheck(socket){
if(spamData[socket.username].spamScore>=maxSpam && !socket.spamViolated){
socket.spamViolated = true;
socket.disconnect();
}
}
function checkSpam(){
for(user in spamData){
if(spamData[user].spamScore>=1) spamData[user].spamScore-=antiSpamRemove;
}
return;
}
setInterval(checkSpam,antiSpam);
function addSpam(socket){
if(socket.spamViolated) return;
spamData[socket.username].spamScore+=1;
maxSpamCheck(socket);
}
// Then add this where your user is authenticated
function authenticate(socket){
socket.username = username // here you define username
socket.spamViolated = false;
spamData[socket.username] = {
spamScore: 0
}
}
Array.prototype.contains = function(k) {
for(var p in this)
if(this[p] === k)
return true;
return false;
};
基本的にすべてのエミットにバインドし、エミット名が含まれているかどうかをチェックします。含まれてspamCheckFunctions
いる場合はスパム ポイントを追加します。ユーザーがスパム スコア量を超えた場合 ( maxSpam
); 彼は切断されます。そして、で定義されたミリ秒ごとに、で定義されantiSpam
たユーザー スパム スコアを引いたものです。antiSpamRemove
よりクリーンなソリューションがあると確信していますが、これは私にとってかなりうまくいきました:)
ユーザーを確認/認証するようにしてください。
これは私がそれらを認証する方法です(nodejsをWebサーバーとして使用していませんが、djangoを使用していました):
io.configure(function(){
io.set('authorization', function(data, accept){
if(data.headers.cookie){
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error', false);
});
});
アクセスできるようsocket.handshake.cookie['sessionid']
になりました(私の場合、これはdjangoで機能しました)。次にsocket.handshake.cookie['sessionid']
、セッションがWebサーバーに保存されているエントリと一致させます