NodeJS - Socket.io 只允许经过 JWT 验证的连接
Posted
技术标签:
【中文标题】NodeJS - Socket.io 只允许经过 JWT 验证的连接【英文标题】:NodeJS - Socket.io allowing only JWT verified connections 【发布时间】:2015-07-20 05:23:04 【问题描述】:我的代码就是这么简单:
/*global require module process console*/
/*eslint-disable*/
(function (require, process)
'use strict';
var config = require('../config')
, uuid = require('node-uuid')
, crypto = require('crypto')
, fs = require('fs')
, port = parseInt(process.env.PORT || config.server.port, 10)
, serverHandler = function (req, res)
res.writeHead(404);
res.end();
, httpUrl
, io
, server;
// Create an http(s) server instance to that socket.io can listen to
if (config.server.secure)
server = require('https').Server(
'key': fs.readFileSync(config.server.key),
'cert': fs.readFileSync(config.server.cert),
'passphrase': config.server.password
, serverHandler);
else
server = require('http').Server(serverHandler);
server.listen(port);
io = require('socket.io').listen(server);
if (config.logLevel)
// https://github.com/Automattic/socket.io/wiki/Configuring-Socket.IO
io.set('log level', config.logLevel);
function describeRoom(name)
var clients = io.sockets.clients(name);
var result =
'clients':
;
clients.forEach(function (client)
result.clients[client.id] = client.resources;
);
return result;
function clientsInRoom(name)
return io.sockets.clients(name).length;
function safeCb(cb)
if (typeof cb === 'function')
return cb;
io.sockets.on('connection', function (client)
client.resources =
'screen': false,
'video': true,
'audio': false
;
// pass a message to another id
client.on('message', function (details)
if (!details)
return;
var otherClient = io.sockets.sockets[details.to];
if (!otherClient)
return;
details.from = client.id;
otherClient.emit('message', details);
);
client.on('shareScreen', function ()
client.resources.screen = true;
);
client.on('unshareScreen', function (type)
client.resources.screen = false;
removeFeed('screen');
);
client.on('join', join);
function removeFeed(type)
if (client.room)
io.sockets.in(client.room).emit('remove',
'id': client.id,
'type': type
);
if (!type)
client.leave(client.room);
client.room = undefined;
function join(name, cb)
// sanity check
if (typeof name !== 'string')
return;
// check if maximum number of clients reached
if (config.rooms
&& config.rooms.maxClients > 0
&& clientsInRoom(name) >= config.rooms.maxClients)
safeCb(cb)('full');
return;
// leave any existing rooms
removeFeed();
safeCb(cb)(null, describeRoom(name));
client.join(name);
client.room = name;
// we don't want to pass 'leave' directly because the
// event type string of 'socket end' gets passed too.
client.on('disconnect', function ()
removeFeed();
);
client.on('leave', function ()
removeFeed();
);
client.on('create', function (name, cb)
if (arguments.length == 2)
cb = (typeof cb == 'function') ? cb : function () ;
name = name || uuid();
else
cb = name;
name = uuid();
// check if exists
if (io.sockets.clients(name).length)
safeCb(cb)('taken');
else
join(name);
safeCb(cb)(null, name);
);
// support for logging full webrtc traces to stdout
// useful for large-scale error monitoring
client.on('trace', function (data)
console.log('trace', JSON.stringify(
[data.type, data.session, data.prefix, data.peer, data.time, data.value]
));
);
// tell client about stun and turn servers and generate nonces
client.emit('stunservers', config.stunservers || []);
// create shared secret nonces for TURN authentication
// the process is described in draft-uberti-behave-turn-rest
var credentials = [];
config.turnservers.forEach(function (server)
var hmac = crypto.createHmac('sha1', server.secret);
// default to 86400 seconds timeout unless specified
var username = Math.floor(new Date().getTime() / 1000) + (server.expiry || 86400) + '';
hmac.update(username);
credentials.push(
'username':username,
'credential':hmac.digest('base64'),
'url':server.url
);
);
client.emit('turnservers', credentials);
);
if (config.uid)
process.setuid(config.uid);
if (config.server.secure)
httpUrl = 'https://localhost:' + port;
else
httpUrl = 'http://localhost:' + port;
console.info('Signaling WS is running at:' + httpUrl);
/*eslint-enable*/
(require, process));
我只想在 socket.io 上只允许经过 jwt 验证的连接,我该怎么做?
实际上我会阻止任何未经 jwt 身份验证的用户连接到 socket.io...
用户通过 express-jwt expressJWT.sign(userProfile, config.secretKey)
方法签名
任何帮助表示感谢!
【问题讨论】:
【参考方案1】:解决了
socketioJwt = require('socketio-jwt');
io.set('authorization', socketioJwt.authorize(
secret: secretKey,
handshake: true
));
【讨论】:
以上是关于NodeJS - Socket.io 只允许经过 JWT 验证的连接的主要内容,如果未能解决你的问题,请参考以下文章
如何允许其他网络连接到服务器 nodejs socket io
NodeJs - express 和 socket.io 同端口集成