I’m a Rails developer new to Phoenix. I would like to try a proof-of-concept stack with Phoenix.
The stack would be a Vue SPA, Flutter mobile app and Phoenix as the backend. I want to try to dump traditional REST API’s and have all data for the SPA and Mobile load via web sockets with a Phoenix channels.
Since all communication would occur over web sockets, I would need a socket connection that would handle unauthenticated tasks like login, sign up, forgot password, etc.
Once you are logged in, I would need a socket connection that is authenticated to perform user-related actions.
I basically have two questions.
Is a socket-only approach a bad idea?
If it is not, what would be the best practice for interacting with channels when some events will need to be authenticated and some will not. ie: login, signup, etc
Hello. I am working on a similar project for which i am considering using Elixir with Pheonix channels as it’s a chat based application. Perhaps we can collaborate and figure things out together.
Putting that aside you would want to use rest or graphql for the login and signup as sockets are really more for real time where you need an always open connection.
I’m trying the approach of authenticating users in each channel’s join/3, but I want to avoid as much boilerplate code as possible.
I extracted a module that looks like this:
defmodule MyAppWeb.AuthorizedChannel do
defmacro __using__({:<>, _, [_topic_prefix, {var_name, _, _} = id_part]} = topic) do
quote location: :keep do
@impl true
def join(unquote(topic) = topic, payload, socket) do
if socket.assigns[:current_user] do
socket = assign(socket, unquote(var_name), unquote(id_part))
handle_post_join(topic, payload, socket)
else
{:error, %{status: "unauthorized"}}
end
end
def handle_post_join(_topic, _payload, socket), do: {:ok, socket}
defoverridable handle_post_join: 3
end
end
end
and here’s how to use it:
defmodule MyAppWeb.FooChannel do
use MyWebApp, :channel
use MyWebApp.AuthorizedChannel, "foo:" <> foo_id
def handle_post_join(_topic, _payload, socket) do
{:ok, assign(socket, :foo, get_foo(socket.assigns.foo_id))}
end
# other stuff except `join/3`
end
@dsalzr I am research elixir for 2 different projects. As i mentioned if you want to do some collaboration perhaps we can put a test project together. I am looking at using sockets as well as liveview for one of the projects.
Always happy to help if you have any specific questions. If you’re just looking to get your feet wet, then I think that my book will be very helpful for you. Chapter 4 is of course going to be the prime chapter for authentication concerns.
I definitely still use and see the value of static forms and requests. User login and signup is a great example of a time that I’d use a plain ol controller/view.