I'm building a web app that has a chat feature. I'm using Laravel 5.4 for the backend and Angular 4 for the front-end.
Everything is working (meaning I can broadcast and recieve) but I'm not at all sure how to secure it. The chat will always be 1 to 1 so its private and has to be secure. Each chat room will have a unique id but somebody could still listen in.
Currently I'm using JWTs for authentication when I make requests from my frontend to my API, but I'm not sure if its possible to implement something similar for this. I know I can pass the token from the frontend using the query
option but than I'm unsure how to parse it and I'm also unsure how to verify that it indeed belongs to the user that is trying to access the chat (should I make a request to the API to verify in server.js
? That doesn't seem efficient. Is it good enough to compare the user id of the token to the user id that will be passed in the data?)
If anybody has any advice or knows a better way to do it, it would be greatly apperciated
Event that is fired off from Laravel when a new message is posted
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');
});
Frontend component
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);
});