Search code examples
ajaxelixirphoenix-frameworkphoenix-channels

How safe and idiomatic would be to use phoenix channels for unauthenticated users instead of ajax


A little context and use case: I have this phoenix app that allows authenticated users to search in database, to retrieve public data. The unauthenticated users use ajax calls and routes to trigger controller and send back a json response to have the same result.

Is it ok to connect somehow unauthenticated users to the private channel maybe as guests or something so that I can ditch ajax calls? How do you solved this in your app?

I create my socket connection like this:

socket = new Socket('/socket', {params: {guardian_token: app.guardian_token}})

If it is possible, what should I be careful about?

Thanks


Solution

  • There is no real reason you cannot do this.

    If you need to return different data depending on if the user is authenticated or not, I would probably do one of

    Create different channel names for authenticated and unauthenticated requests.

    "authenticated:room:4" and "unauthenticated:room:4". You may also want to create an MyApp.Authenticated.RoomChannel module and a MyApp.Unauthenticated.RoomChannel. Though, this could get a little out of hand if you have a lot of channels.

    Create different branches inside the handle_in/3 functions.

    In your join function, put a marker on the socket stating whether the user is authenticated or not. Then, in your handle_in/3 functions you can do something like

    def handle_in(msg, params, socket) do
      if socket.assigns.authenticated do
        authenticated_request(msg, params, socket)
      else
        unauthenticated_request(msg, params, socket)
      end
    end
    

    However, if there is no data difference between the authenticated and unauthenticated requests, there is no additional overhead. Just do the thing the user asked.