Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private channels with Pusherapp (using Rails)

I just got through the hello world for Pusherapp. Now I want to create private channels so users only read messages that they are supposed to read.

The Pusher docs only give some details on how to do this, and I'm kind of lost.

From the docs:

... The Pusher JS library is returned a socket_id when it connects to Pusher.

When it attempts to subscribe to a private channel, it sends back an AJAX request to your server with the channel_name and socket_id as parameters.

The default URL for this is http://yourserver.com/pusher/auth. ...

class PusherController < ApplicationController
  def auth
    if current_user
      response = Pusher[params[:channel_name]].authenticate(params[:socket_id])
      render :json => response
    else
      render :text => "Not authorized", :status => '403'
    end
  end
end

Given a unique user id (current_user.id), how can I authenticate that user then have him/her subscribe to the corresponding channel?

Thanks

like image 386
user94154 Avatar asked Dec 22 '22 17:12

user94154


1 Answers

This blog post on the implementation seems to explain things a bit more: https://pusher.com/docs/client_api_guide/client_private_channels

The authorization scheme is based on the idea that, rather than implementing custom user authentication, and adding complexity and state to pusher, we should trust the existing level of authentication offered by your application. We also wanted to ensure that someone reading data sent from your application to the browser would not be able to connect to a channel as that user, and therefore couldn't include any secrets in the page HTML.

Sounds like your application's business logic should authenticate the user and decide that they should access the private channel.

Their diagram shows:

enter image description here

Once authenticated, the app requests to subscribe the user. Pusher replies with the socket_id. Then they are connected using that.

Here's how they describe it:

As shown in this diagram, a unique socket id is generated and sent to the browser by Pusher. This is sent to your application (1) via an AJAX request which authorizes the user to access the channel against your existing authentication system. If successful your application returns an authorization string to the browser signed with you Pusher secret. This is sent to Pusher over the WebSocket, which completes the authorization (2) if the authorization string matches.

The example at the bottom of the blog post further clarifies:

Suppose you have a channel called project-3, to which users A and B have access, but not C. You'd like to make this channel private so that user C cannot listen in on the private events. Simply send events to private-project-3 and subscribe to it in the browser. As long as you're using the latest javascript (version 1.3 or above), you'll see that a POST request is made to your application to /pusher/auth. This will currently fail, and therefore the subscribe request will not be made to the socket.

So, to me this sounds like: 1) Request to subscribe is sent to Pusher 2) Pusher POSTs to your /auth method to determine if the user can access the channel 3) If your business logic allows the user to access this channel, the auth method returns the "ok" response:

auth = Pusher[params[:channel_name]].socket_auth(params[:socket_id])

    content_type 'application/json'
    return JSON.generate({
      :auth => auth
    })

I haven't used Pusher itself, but its model seems to mirror the structure of other push-based models. Hope this helps!

like image 75
shedd Avatar answered Jan 04 '23 23:01

shedd