使用 socket.io 和 Laravel Echo 时如何保护私有频道?
Posted
技术标签:
【中文标题】使用 socket.io 和 Laravel Echo 时如何保护私有频道?【英文标题】:How to guard private channels when using socket.io and Laravel Echo? 【发布时间】:2017-06-24 12:09:45 【问题描述】:这是我的server.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();
http.listen(3000, function()
console.log('Listening on Port 3000');
);
redis.psubscribe('*', function(err, count)
console.log(err, count);
);
redis.on('pmessage', function(subscribed, channel, message)
message = JSON.parse(message);
io.emit(message.event, channel, message.data);
);
还有一个简单的事件:
class FieldWasUpdated implements ShouldBroadcast
use InteractsWithSockets, SerializesModels;
public $instance;
public $key;
public $value;
public function __construct($instance, $key, $value)
$this->instance = $instance;
$this->key = $key;
$this->value = $value;
public function broadcastOn()
return new PrivateChannel("model." . $this->instance->getModelType() . "." . $this->instance->id);
客户端连接socket.io:
Echo = new Echo(
broadcaster: 'socket.io',
host: window.location.hostname + ':3000'
);
然后监听事件(在 Blade 模板中):
var channel = "model. $instance->getModelType() . $instance->id ";
Echo.private(channel)
.listen("FieldWasUpdated", function(e)
window.VueBus.$emit("updated", channel, e.key, e.value);
)
.listen("FieldBecameDisabled", function(e)
window.VueBus.$emit("disabled", channel, e.key);
);
问题是:没有处理认证,任何用户都可以订阅这些频道。
Broadcast::channel("model.announcement.*", function($user, $id)
return false; // this function is not called
)
这是来自 Chrome 开发者控制台 (WebSocket) 的示例事件:
[
"App\\Events\\FieldWasUpdated",
"private-model.announcement.2",
"instance":
"type":"ANN_TYPE_MISSED_CALL",
"status":"ANN_STATUS_CANCELLED",
"name":"1233421",
"phone":"+7(222)222-3322",
"email":"sdgsg@mail.com",
"message":"sdgdsgsdgdfdg",
"requirement":null,
"web_type":"ANN_WEB_TYPE_UNKNOWN",
"url":null,
"responsible_id":19,
"recommender_id":18
,
"key":"message",
"value":"sdgdsgsdgdfdg"
]
同样没有/broadcast/auth
URL,但BroadcastServiceProvider
调用了Broadcast::routes();
,当浏览器加载时,不会调用/broadcast/auth
。
【问题讨论】:
尝试 Broadcast::channel("model.announcement.*", function($user, $id) abort(401); ) 【参考方案1】:Laravel 文档在广播一章中对此进行了详细介绍:https://laravel.com/docs/5.5/broadcasting#presence-channels。 Authorizing Presence Channels 部分应该与私人频道相同。
【讨论】:
以上是关于使用 socket.io 和 Laravel Echo 时如何保护私有频道?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5:使用 Laravel 会话数据的 Socket.io 客户端身份验证
使用 socket.io 和 Laravel Echo 时如何保护私有频道?
CORS、Laravel Valet 和 Socket.io