如何保护Redis&Socket.IO实时服务器,以便只有经过身份验证的用户才能收听?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何保护Redis&Socket.IO实时服务器,以便只有经过身份验证的用户才能收听?相关的知识,希望对你有一定的参考价值。
我正在构建一个具有聊天功能的网络应用。我使用Laravel 5.4作为后端,Angular 4作为前端。
一切正常(意味着我可以播放和接收),但我不确定如何保护它。聊天将始终是1比1,所以它是私人的,必须是安全的。每个聊天室都有一个唯一的ID,但有人仍然可以收听。
目前,当我从我的前端向我的API发出请求时,我正在使用JWT进行身份验证,但我不确定是否可以为此实现类似的功能。我知道我可以使用query
选项从前端传递令牌,但我不确定如何解析它,我也不确定如何验证它确实属于试图访问聊天的用户(我应该请求API在server.js
中验证?这看起来效率不高。将令牌的用户ID与将在数据中传递的用户ID进行比较是否足够好?)
如果有人有任何建议或知道更好的方法,那将会非常有用
发布新消息时从Laravel发起的事件
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $data;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
$this->data = array(
'message'=> 'hi'
);
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('chat');
}
}
server.js(node.js)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.psubscribe('private-chat', function(err, count) {
console.log('psubscribe');
});
redis.on('pmessage', function(subscribed, channel, message) {
console.log('pmessage', subscribed, channel, message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
前端组件
socket: io.Socket;
this.socket = io.connect("http://webapp.test:3000", { query: this.token });
this.socket.on("private-chat:App\Events\NewMessage", (data) =>
{
console.log("Data", data);
});
尝试使用SSL(机密性)
我们知道SSL确保您正在与之通信的服务器实际上是您想要的Web服务。
身份验证(避免certificate pinning)
在你使用authentication
和JWT
的情况下你需要HS256
,我强烈建议你在这种情况下使用RS256 algorythm JWT
私钥和公钥。
如果您不确定谁在另一端(身份验证),那么没有其他人可以听你们俩之间的对话并不重要。
因为我将以如下方式构建应用程序:如果两个通道之间的会话authentication
未设置,则永远不会展开正在发送的数据的内容。
独特的会话
因为slong作为你的服务使用JWT
认证你送回他们authentication token
。这就像随机数或GUID
一样简单。在此会话期间,此标识符将作为在此通道上发送或接收数据的任何请求的一部分,但只有在此特定会话打开时才会在此特定通道上接受。
还有一项安全检查:链接reply attack
我给了你每天使用的提示,以安全地与中央银行来回发送数据(所以遵循这些提示,我认为你的应用应该非常安全)
UPDATE
如何处理JWT
创建一个新的中间件qazxsw poi,因为laravel中的中间件是核心供应商的外层,这意味着如果身份验证失败,它就会在核心层中的外层失败。
在Verify JWT token
中间件下分组路线!
创建一个Verify JWT token
,这可能是在RedisRepository
下。该类应负责从redis获取数据。
在中间件解密用户JWT上获取解密的有效负载(这可能是用户UUID或ID)。
如果正认证通过,则从RedisRepository获取AppRedisRepository
与解密的有效负载进行比较,否则中止403未经认证!
以上是关于如何保护Redis&Socket.IO实时服务器,以便只有经过身份验证的用户才能收听?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 socket.io-redis 发送私人消息(发射)
Socket.io & Redis - 适合 io 游戏的架构?
Node.js、Socket.io、Redis pub/sub 大容量、低延迟困难
如何在前端获取 socket.on 函数?事件被触发和处理。我正在使用 socket.io、NodeJS 服务器和 Redis.io