我正在构建一个具有聊天功能的网络应用。我使用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);
});
答案 0 :(得分:1)
尝试使用SSL (机密性)
我们知道SSL确保您正在与之通信的服务器实际上是您想要的Web服务。
身份验证(避免certificate pinning)
如果您使用authentication
并JWT
,则需要HS256
我强烈建议您在私有和公钥的情况下使用RS256 algorythm JWT
。
如果您不确定谁在另一端(身份验证),那么没有其他人可以听你们俩之间的对话并不重要。
由于我将以如下方式构建应用程序:如果两个通道之间的会话authentication
未设置,则永远不会展开正在发送的数据的内容。
独特会话
由于您的服务使用JWT
进行身份验证,因此您需要将authentication token
发回给我们。这就像随机数或GUID
一样简单。在此会话期间,此标识符将作为在此频道上发送或接收数据的任何请求的一部分,但只有在此特定频道上才会被接受,并且只有在此唯一会话开放时才会被接受。
再进行一次安全检查:链接reply attack
我向您提供了我每天使用的提示,以便与中央银行来回发送数据(因此遵循这些提示我认为您的应用应该非常安全)
<强>更新强>
如何处理 JWT
创建一个新的中间件Verify JWT token
,因为laravel中的中间件是核心供应商的外层,这意味着如果验证失败,它就会在核心层中的外层失败。
将路由分组到Verify JWT token
中间件下!
创建RedisRepository
这可以在App\RedisRepository
下。该类应负责从redis中获取数据。
在中间件解密用户JWT上获取解密的有效负载(这可能是用户UUID或ID)。
从RedisRepository中获取user ID
与解密的有效负载进行比较,如果正认证通过,则中止403未经认证!