Authentication Socket.IO身份验证
我尝试在Node.js中使用Socket.IO,并尝试允许服务器为每个Socket.IO客户端提供一个标识。由于套接字代码不在http服务器代码的范围内,因此无法轻松访问发送的请求信息,因此我假设需要在连接期间发送它。最好的方法是什么 1) 通过Socket.IO向服务器获取有关谁正在连接的信息Authentication Socket.IO身份验证,authentication,node.js,express,socket.io,Authentication,Node.js,Express,Socket.io,我尝试在Node.js中使用Socket.IO,并尝试允许服务器为每个Socket.IO客户端提供一个标识。由于套接字代码不在http服务器代码的范围内,因此无法轻松访问发送的请求信息,因此我假设需要在连接期间发送它。最好的方法是什么 1) 通过Socket.IO向服务器获取有关谁正在连接的信息 2) 验证他们所说的身份(我目前正在使用Express,如果这能让事情变得更简单的话)使用connect redis,并将redis作为所有已验证用户的会话存储。确保在身份验证时将密钥(通常为req.s
2) 验证他们所说的身份(我目前正在使用Express,如果这能让事情变得更简单的话)使用connect redis,并将redis作为所有已验证用户的会话存储。确保在身份验证时将密钥(通常为req.sessionID)发送到客户端。让客户端将此密钥存储在cookie中 在socket connect上(或以后任何时候),从cookie中获取此密钥并将其发送回服务器。使用此键在redis中获取会话信息。(获取密钥) 例如: 服务器端(以redis作为会话存储):
请求会话.重新生成。。。
res.send({rediskey:req.sessionID});
客户端:
//将密钥存储在cookie中
SetCookie('rediskey',)//http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
//然后,当连接套接字时,从document.cookie中获取rediskey并将其发送回服务器
var socket=新io.socket();
socket.on('connect',function(){
var rediskey=GetCookie('rediskey')//http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
send({rediskey:rediskey});
});
服务器端:
//in io.on('connection')
io.on('connection', function(client) {
client.on('message', function(message) {
if(message.rediskey) {
//fetch session info from redis
redisclient.get(message.rediskey, function(e, c) {
client.user_logged_in = c.username;
});
}
});
});
我也喜欢你的方式
生成一个唯一的套接字id,并
由推送器发送到浏览器。这是
通过电子邮件发送到您的应用程序(1)
授权用户的AJAX请求
根据您的
现有的认证系统。如果
成功的应用程序将返回一个
将授权字符串添加到浏览器
和你签的是Pusher机密。这是
发送至腹板箱上方的推进器,
这就完成了授权(2)
如果授权字符串匹配
因为,socket.io
对每个套接字都有唯一的套接字id
socket.on('connect', function() {
console.log(socket.transport.sessionid);
});
他们过去常常授权用户
我还没有将其镜像到socket.io,但我认为这可能是一个非常有趣的概念
//server side
io.sockets.on('connection', function (con) {
console.log(con.id)
})
//client side
var io = io.connect('http://...')
console.log(io.sessionid)
本文()展示了如何
- 在Redis中存储HTTP服务器的会话(使用Predis)
- 通过cookie中发送的会话id从node.js中的Redis获取这些会话
var io = require('socket.io').listen(8081);
var cookie = require('cookie');
var redis = require('redis'), client = redis.createClient();
io.sockets.on('connection', function (socket) {
var cookies = cookie.parse(socket.handshake.headers['cookie']);
console.log(cookies.PHPSESSID);
client.get('sessions/' + cookies.PHPSESSID, function(err, reply) {
console.log(JSON.parse(reply));
});
});
我知道这有点老了,但是对于未来的读者来说,除了解析cookie和从存储中检索会话(例如),你也可以考虑基于令牌的方法。 在本例中,我使用非常标准的JSON Web标记。您必须向客户端页面提供令牌,在本例中,想象一个返回JWT的身份验证端点:
var jwt = require('jsonwebtoken');
// other requires
app.post('/login', function (req, res) {
// TODO: validate the actual user user
var profile = {
first_name: 'John',
last_name: 'Doe',
email: 'john@doe.com',
id: 123
};
// we are sending the profile in the token
var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 });
res.json({token: token});
});
现在,您的socket.io服务器可以按如下方式配置:
var socketioJwt = require('socketio-jwt');
var sio = socketIo.listen(server);
sio.set('authorization', socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
sio.sockets
.on('connection', function (socket) {
console.log(socket.handshake.decoded_token.email, 'has joined');
//socket.on('event');
});
socket.io-jwt中间件需要查询字符串中的令牌,因此从客户端连接时只需附加它:
var socket = io.connect('', {
query: 'token=' + token
});
我对这个方法和cookies做了更详细的解释。在c/s之间使用session和Redis 服务器端
io.use(函数(套接字,下一个){
//到达这里会话id
log(socket.handshake.headers.cookie);并从redis会话数据进行匹配
next();
});
以下是我尝试让以下工作正常进行的步骤:
- 快车:4.14
- socket.io:1.5
- passport(使用会话):0.3
- redis:2.6(处理会话的数据结构非常快;但您也可以使用其他类似MongoDB的数据结构。不过,我建议您将其用于会话数据+MongoDB来存储其他持久数据,如用户)
server.js 以下摘录仅包括设置以前的技术所需的所有内容。您可以看到我在一个项目中使用的完整的server.js版本
从“http”导入http;
从“快递”进口快递;
从“护照”进口护照;
从“redis”导入{createClient as createRedisClient};
从“连接redis”导入connectRedis;
从“socket.io”导入Socketio;
//您自己的套接字处理程序文件,它是可选的。解释如下。
从“./sockets”导入socketConnectionHandler;
//关于Redis会话数据结构的配置。
const redisClient=createRedisClient();
const redistore=connectRedis(会话);
const dbSession=new redistore({
客户:我的客户,
主机:“localhost”,
港口:27017,
前缀:'stackoverflow_382;',
disableTTL:对
});
//让我们将Express配置为使用Redis存储来处理
//会议也是如此。您可能需要Express来处理您的问题
//会话,并与socket.io共享相同的存储
//确实如此(即用于处理AJAX登录)。
const session=会话({
雷萨夫:是的,
saveUninitialized:true,
key:'SID',//这将用于会话cookie标识符
秘密:“秘密密钥”,
门店:dbSession
});
应用程序使用(会话);
//让我们使用他们的中间件初始化passport,这可以
//一切几乎都是自动完成的。(您必须配置登录
///自行注册策略(参见参考文献1)
app.use(passport.initialize());
app.use(passport.session());
//Socket.IO
常量io=Socketio(服务器);
io.use((套接字,下一个)=>{
会话(socket.handshake,{},next);
});
io.on('connection',socketConnectionHandler);
//socket.io已准备就绪;请记住^this^变量只是
//我们为自己的socket.io处理程序文件指定的名称(已解释)
//就在这之后)。
//启动服务器。此wil