Express + Socket.io:在查询字符串中为除一个事件之外的每个事件查找键
Express + Socket.io: find key in query string for every event except one
我想允许任何套接字连接到我的服务器,但如果客户端连接时没有在 socket.handshake.query 中指定 'username',我想要让他创建一个新帐户然后服务器应该自动断开他。
我能实现它的唯一方法是在除 signUp 事件之外的每个事件上验证 socket.handshake.query - 这意味着运行几乎在每个事件上都使用 validateQuery()!-。我觉得这可能是一种非常粗糙的方式。我也尝试过使用中间件来实现它,但我无法实现所需的行为(我对 Node 还很陌生)。
这是我的代码,如果您知道更好的实现方法,请告诉我:)
注意:对于这种情况,会话处理程序不是必需的。
'use strict';
/*** BASE SETUP: Main objects & Dependencies */
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io');
// Set port in which the server will listen
var port = process.env.PORT || 3000;
// Start servers (HTTP is temporal and just for personal tests...)
var io = io.listen(server);
server.listen(port, function() {
console.log('>> Express server listening on port ' + port + ' <<');
});
/*
* A dummy socket validation function.
*/
var validateQuery = function(socket, next) {
console.log("> Verifying username...");
if ( typeof socket.handshake.query.username === 'undefined' || socket.handshake.query.username === "" ) {
console.log("-> Authentification failed!");
socket.disconnect();
return next(new Error("{ code: 403, description: 'You must specify a username in your query' }"));
}
};
/*** SOCKET IO Events */
io.sockets.on('connection', function(socket) {
console.log("> New connection stablished: "+ socket.id);
// @ Disconnect
//
socket.on('disconnect', function() {
// clients.splice(clients.indexOf(socket.id), 1);
console.log("> Triggered 'Disconnect' @ " + socket.id);
});
// @ SignUp - Creates new users
//
socket.on('signUp', function( requestData ) {
console.log("> Triggered 'signUp' @ " + socket.id);
socket.emit('onSignUp', { username : requestData.username, dsp : requestData.dsp });
socket.disconnect();
});
// @ getUserList - Gets a list of all registered users
//
socket.on('getUserList', function( requestData ) {
// Validate query
validateQuery(socket);
// Send the user's list
socket.emit( 'onGetUserList', userList );
});
// @ getUserProfile - Gets a user's profile. Will return the requester's profile if none specified
//
socket.on('getUserProfile', function( requestData ) {
// Validate username
validateQuery(socket);
var userProfile = { username : "User1", dsp : "Ron" };
socket.emit('onGetUserProfile', userProfile);
});
});
如果您想允许不经过身份验证的连接,但只允许处理某些未经身份验证的事件,那么您将必须检查每个需要身份验证的事件的验证。如果您要在未经授权的情况下允许某些事件通过,则别无他法。
不过,您可以使身份验证检查更简单一些。当套接字首次连接时,您可以进行验证,然后在套接字对象上设置自定义标志。从那时起,如果事件需要身份验证,您可以只检查该标志(这应该更有效率)。
如果任何后续事件可能会更改身份验证状态,您可以更新标志。
您还可以为需要身份验证的事件处理程序创建一些快捷方式。
function addAuthEventListener(sock, event, fn) {
sock.on(event, function (data) {
if ( typeof sock.handshake.query.username === 'undefined' || sock.handshake.query.username === "" ) {
sock.disconnect();
} else {
return fn.apply(this, arguments)
}
});
}
因此,任何需要身份验证的事件处理程序都可以像这样安装:
addAuthEventListener(socket, 'onGetUserList', function(requestData) {
// Send the user's list
socket.emit( 'onGetUserList', userList );
});
并且身份验证检查会自动进行。
我想允许任何套接字连接到我的服务器,但如果客户端连接时没有在 socket.handshake.query 中指定 'username',我想要让他创建一个新帐户然后服务器应该自动断开他。
我能实现它的唯一方法是在除 signUp 事件之外的每个事件上验证 socket.handshake.query - 这意味着运行几乎在每个事件上都使用 validateQuery()!-。我觉得这可能是一种非常粗糙的方式。我也尝试过使用中间件来实现它,但我无法实现所需的行为(我对 Node 还很陌生)。
这是我的代码,如果您知道更好的实现方法,请告诉我:)
注意:对于这种情况,会话处理程序不是必需的。
'use strict';
/*** BASE SETUP: Main objects & Dependencies */ var express = require('express'); var app = express(); var http = require('http'); var server = http.createServer(app); var io = require('socket.io'); // Set port in which the server will listen var port = process.env.PORT || 3000; // Start servers (HTTP is temporal and just for personal tests...) var io = io.listen(server); server.listen(port, function() { console.log('>> Express server listening on port ' + port + ' <<'); }); /* * A dummy socket validation function. */ var validateQuery = function(socket, next) { console.log("> Verifying username..."); if ( typeof socket.handshake.query.username === 'undefined' || socket.handshake.query.username === "" ) { console.log("-> Authentification failed!"); socket.disconnect(); return next(new Error("{ code: 403, description: 'You must specify a username in your query' }")); } }; /*** SOCKET IO Events */ io.sockets.on('connection', function(socket) { console.log("> New connection stablished: "+ socket.id); // @ Disconnect // socket.on('disconnect', function() { // clients.splice(clients.indexOf(socket.id), 1); console.log("> Triggered 'Disconnect' @ " + socket.id); }); // @ SignUp - Creates new users // socket.on('signUp', function( requestData ) { console.log("> Triggered 'signUp' @ " + socket.id); socket.emit('onSignUp', { username : requestData.username, dsp : requestData.dsp }); socket.disconnect(); }); // @ getUserList - Gets a list of all registered users // socket.on('getUserList', function( requestData ) { // Validate query validateQuery(socket); // Send the user's list socket.emit( 'onGetUserList', userList ); }); // @ getUserProfile - Gets a user's profile. Will return the requester's profile if none specified // socket.on('getUserProfile', function( requestData ) { // Validate username validateQuery(socket); var userProfile = { username : "User1", dsp : "Ron" }; socket.emit('onGetUserProfile', userProfile); }); });
如果您想允许不经过身份验证的连接,但只允许处理某些未经身份验证的事件,那么您将必须检查每个需要身份验证的事件的验证。如果您要在未经授权的情况下允许某些事件通过,则别无他法。
不过,您可以使身份验证检查更简单一些。当套接字首次连接时,您可以进行验证,然后在套接字对象上设置自定义标志。从那时起,如果事件需要身份验证,您可以只检查该标志(这应该更有效率)。
如果任何后续事件可能会更改身份验证状态,您可以更新标志。
您还可以为需要身份验证的事件处理程序创建一些快捷方式。
function addAuthEventListener(sock, event, fn) {
sock.on(event, function (data) {
if ( typeof sock.handshake.query.username === 'undefined' || sock.handshake.query.username === "" ) {
sock.disconnect();
} else {
return fn.apply(this, arguments)
}
});
}
因此,任何需要身份验证的事件处理程序都可以像这样安装:
addAuthEventListener(socket, 'onGetUserList', function(requestData) {
// Send the user's list
socket.emit( 'onGetUserList', userList );
});
并且身份验证检查会自动进行。