您的位置:首页 > 其它

基于JWT的Socket.io用户认证

2016-05-17 22:08 537 查看
转载请注明出处:

http://blog.csdn.net/Soaring_Tiger/article/details/51439605

翻译自 Token-based Authentication with Socket.IO 原文标题及内容略有删改

在实时框架里进行用户认证(Authentication)是非常有挑战的一件事,因为实时系统与常规的web app是有很大差别的。其风险在于如果没有准确的进行用户认证,那么你很可能就会把数据流发送到错误的用户那里去。因为socket系统不能自动的知道谁是登录用户,因此理论上任何人都可以加入到数据流当中。

图1.很多人会误用的Socket.IO认证方式



很多人错误的认为:只要用户在页面上登录了一次,那么就可以自动的在socket stream数据流中得到认证。实际上这是两个完全不同的通道(channels)。

有两种思路可以解决上述问题,一种是传统的基于cookie的认证方式,还有一种是基于JWT(JSON Web Tokens)的认证方式,下图是两种方式的比较:


图2

对于两种方法的比较,我们另文再讨论,现在就介绍一下基于JWT的认证实现。

基于JWT的Socket.IO认证

服务端端的实现

var jwt = require('jsonwebtoken');
// 其它的库此处略掉...

app.post('/login', function (req, res) {

// TODO: 验证实际用户
var profile = {
first_name: 'John',
last_name: 'Doe',
email: 'john@doe.com',
id: 123
};

// 将用户信息加密在令牌内
var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 });

res.json({token: token});
});

var server = http.createServer(app);


然后是socket.io的相关代码:

var socketioJwt = require('socketio-jwt');

var sio = socketIo.listen(server);

sio.set('authorization', socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
//上述JWT用密钥 jwtSecret 签名加密。
sio.sockets
.on('connection', function (socket) {
console.log(socket.handshake.decoded_token.email, 'connected');
//socket.on('event');
});

server.listen(9000, function () {
console.log('listening on http://localhost:9000'); });


在与socket.io客户端握手的时候,要求验证JWT,如果JWT是正确的,那么连接(connection)事件就被触发了。

客户端的实现

function connect_socket (token) {
var socket = io.connect('', {
query: 'token=' + token
});

socket.on('connect', function () {
console.log('authenticated');
}).on('disconnect', function () {
console.log('disconnected');
});
}

$('#login').submit(function (e) {
e.preventDefault();
$.post('/login', {
username: $('username').val(),
password: $('password').val()
}).done(function (result) {
connect_socket(result.token);
});
});


完整实现的代码见Git
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: