Giter VIP home page Giter VIP logo

Comments (15)

tlaverdure avatar tlaverdure commented on July 20, 2024 8

Yeah I've got some ideas on how to secure channels. I'm working on adding something like this to an API for an app I'm building. I'll throw out some examples namespaced with "echo" in hopes that it will convince. 😄

Server-side - Node (New npm package?)

var EchoServer = require('laravel-echo-server'); //I've got a working prototype

var echo = new EchoServer();

echo.run();

with options

var options = {
  host: 'http://localhost:6001',
  authEndpoint: '/broadcasting/auth', //endpoint to post authorization
  privateChannels: ['notifications-*'] //assign private channels, default private-*
};

new EchoServer(options);

Server-side - PHP (New Laravel package?)

  • When notifications are requested GET /notifications create a token associated to a user echoToken()->create($user, 'notifications-user-1')
  • Return notifications along with a single-use echo_token {notifications: [], echo_token: '...'}
  • Node server POSTs the echo_token to Laravel to be authenticated POST /broadcasting/auth, if user's token matches the private-channel return 200 OK

Client-side

var notifications;
var Echo = require('laravel-echo');

//initial request to notifications
fetch('/notifications').then(function(res) {
  notifications = res.notifications;

  var echo = new Echo({
    provider: 'socket.io',
    channel: 'notifications-user-1',
    echo_token: res.echo_token
  });

  echo.listen('notifications-user-1', function () {
    //listen for new notifications, only if authenticated
  });
});

from echo.

simonj avatar simonj commented on July 20, 2024

Would be nice 😀

from echo.

taylorotwell avatar taylorotwell commented on July 20, 2024

Lack of good authentication mechanisms at the channel level is the main problem. If that can be solved cleanly that would be good.

from echo.

tlaverdure avatar tlaverdure commented on July 20, 2024

Just watched the Laracast on Echo! The new broadcast driver would eliminate the need of an additional package that issues tokens as I suggested above. Much cleaner approach @taylorotwell 👏 .

I looked at the 5.3-dev branch and noticed that the RedisBroadcaster would need to be updated like the PusherBroadcaster. Assuming that both pusher and socket.io would use the /broadcasting/auth endpoint. I can send a PR, but is there anything else that I need to be aware of to make use of the new BroadcastServiceProvider?

Also, I'm having trouble pinpointing where the Broadcast::channel() method is at. Is that feature finished yet?

I'm also still experimenting with some ideas on how to handle channel auth. I'm up to the point where I need to check auth with laravel before allowing a user to join a channel. Check this out:
https://github.com/tlaverdure/laravel-echo-server

Thanks!

from echo.

taylorotwell avatar taylorotwell commented on July 20, 2024

Cool :)

from echo.

leemason avatar leemason commented on July 20, 2024

ahem: https://github.com/leemason/rebound-client will have some docs and the redis/node server p tonight as well, stay tuned.

@taylorotwell i spoke to you about tis on twitter when you launched echo.

Ive spent along time trying to get socket.io to work and basically while possible, its alot of workarounds due to socket.io being so opinionated.

so i took engine.io and built a channel driven client (and server, nearly ready). im trying to keep the same api, but there are most likley going to be subtle differences.

from echo.

leemason avatar leemason commented on July 20, 2024

and heres the server package: https://github.com/leemason/rebound-server

@tlaverdure ive done it a different way, when a channel subscription is requested i send a post request to laravel with the original socket request headers (has all session stuff in it, and the socket id in a cookie).

the post requests either returns success=true and user object, or fails.

if it returns success the user object is saved against the socket on the node server, and added to a channels array.

when redis messages are fetched by the server, it doesnt just send to all sockets, it sends only to the sockets subscribed to that channel, and they cant be subcribed to that channel unless the post request was a success.

this way we offload all the auth stuff to laravel, and the node server simply passes messages along, theres no way for an unauthenticated socket to recieve messages as there not added to the channels.

its not socket io, but it has the same long polling fallbacks and reconnection stuff.

@taylorotwell is the interface for socket authentication routes, usable methods etc set in stone now for 5.3? id like to get a pull request ready and maintain a unified api if we can?

from echo.

taylorotwell avatar taylorotwell commented on July 20, 2024

Yes I think those methods are pretty solid so go ahead.

On Sun, May 22, 2016 at 12:45 PM -0700, "Lee Mason" [email protected] wrote:

and heres the server package: https://github.com/leemason/rebound-server

@tlaverdure ive done it a different way, when a channel subscription is requested i send a post request to laravel with the original socket request headers (has all session stuff in it, and the socket id in a cookie).

the post requests either returns success=true and user object, or fails.

if it returns success the user object is saved against the socket on the node server, and added to a channels array.

when redis messages are fetched by the server, it doesnt just send to all sockets, it sends only to the sockets subscribed to that channel, and they cant be subcribed to that channel unless the post request was a success.

this way we offload all the auth stuff to laravel, and the node server simply passes messages along, theres no way for an unauthenticated socket to recieve messages as there not added to the channels.

its not socket io, but it has the same long polling fallbacks and reconnection stuff.

@taylorotwell is the interface for socket authentication routes, usable methods etc set in stone now for 5.3? id like to get a pull request ready and maintain a unified api if we can?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

from echo.

lukepolo avatar lukepolo commented on July 20, 2024

You could also store the channels in the session so you can join them on reconnect, would be annoying to make lots of extra requests on refresh.

Here is my implementation, but rooms are based on url (cause auth doesn't really in my app, and cannot join rooms any other way)

https://gist.github.com/lukepolo/58de479335e86ec2abba20f6c112f2fa

from echo.

leemason avatar leemason commented on July 20, 2024

yeah possibly, love that gist, does it work well for you?

personally id prefer to keep any sort of logic within the laravel app and run the socket server just as a intermediary which is what rebound is trying to solve, but as youve shown theres more than 1 way to skin a cat.

i dont like the idea of handling session and/or cookie information in two places, trying to let laravel handle all of that.

wasnt aware of that dotdev package, thats real nice, will add that to my examples.

from echo.

lukepolo avatar lukepolo commented on July 20, 2024

It works very well as I have been using this method for around 2 years on my application.

The reasoning behind touching the session is you can reject them ever connecting the server if they do not have a valid session. This is handy for rejecting anyone outside the application trying to connect.

I assume sure you know the socket.id change on every connect and you disconnect on all channels every refresh. To lower overhead on the number of requests you would store them in the session and use it in node. But I see your concern handling them in both places, but is that really a bad thing in this case ?

Ill look deeper into your code today ~

from echo.

leemason avatar leemason commented on July 20, 2024

yeah totally get your point, like i said your code is awesome. would be a good idea to add some sort of persistance.

the only reason i mention it, is it feels a bit hacky to deconstruct the encrypted laravel session in the node app, im still looking into it and your gist should help alot with that.

the aim of rebound really is to mimic the echo package, but be free usage AND be pretty much set and forget. had a good session on it today and yesterday and its in a working state, would love to see what you think.

from echo.

lukepolo avatar lukepolo commented on July 20, 2024

Awesome, ill try pulling in the latest changes and give it a go later tonight.

from echo.

leemason avatar leemason commented on July 20, 2024

yeah just reviewing your gist again to see if there are any quick wins. but not everybody is going to be using a redis session store (most likley as rebound uses redis for the events, but cant guarantee it).

still early days, we can optimize as we go along, 5.3 isnt even out yet so i think we have time.

from echo.

leemason avatar leemason commented on July 20, 2024

@lukepolo ive got round this now with the latest version. i open up another reis connection on the same db.

then when a socket gets saved in laravel, it returns the user id (if logged in). this gets saved against the socket.

when subscription to a channel happens, the cache is checked for "rebound:channel_name:user_id", which can contain the member info. (we saved the socket user id earlier on connect).

if cache missed = perform post auth check (and cache results)
if cache string is false = return without subscribing (auth failed)
if cache json parse and set member info from cache

this means the first visit forces the post request. every single request after that fetches the data from redis cache so no more post requests, and no session trickery.

take a look when you get chance.

from echo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.