skyqrose

skyqrose

Proposal:
I wish the socket connect/3 callback could allow returning a reply to the frontend, which would then be visible in phoenix.js as an argument to the callback given to socket.onOpen.

I think this would be straightforward to add to successful connections, which is my main request.

It would be harder but even more useful if a reason could be passed to the frontend for rejecting a connection.

Use Case:
I want to reject a socket connection and tell the frontend why.

Currently, phoenix can use the error_handler config (docs) to say why a connection was rejected, and this reaches the browser (it’s visible in dev tools) but it’s not visible to phoenix.js. The arguments to the onError and onClose callbacks are identical no matter what error is sent, and they’re even identical to the error that phoenix.js receives when there’s a network error.

My JS app needs to tell different connection errors apart in order to handle them differently. On a network error it should try again (the deafult). On an authn error it should not try again and should redirect to the login page. If the frontend app version is outdated it should refresh. Other applications may have app-specific handlers for other errors.

Workaround:
Because I can’t send a useful error message, I allow the socket to connect, even if there are authentication problems, and then store the auth details in socket.assigns, and check authentication on every channel join.

Then, I wish I could reply to the socket connect to tell the client about any authentication problems so that the frontend could handle them. But there’s no way to reply with a payload to socket connect/3. So instead, I need a workaround within my workaround:

After successfully connecting to a socket, the client immediately joins a channel within that socket (I named it “metadata”), and that channel replies to the join with a payload that describes any authentication or other problems that the client should handle in a custom way.

If a socket fails to connect, the client can know that it’s definitely because of network problems, not auth problems, and it can retry in the default way.

Including a reply with a rejected socket connection:
This would most directly address my use case, but might be difficult. There’s probably a reason that browsers don’t expose websocket connection failures to JS. It might require backwards incompatible changes to how error handlers for connect/3 are done. I’d like this idea to be at least considered, but it’s okay with me if there’s reasons not to do it.

I saw a number of other threads on this forum and others about this issue, so I think it’s something that many people are running into.

Including a reply with an accepted socket connection:
This would make my workaround much simpler. I wouldn’t need the separate “metadata” channel, and it’d save a network round trip during the connection process. I could send any authentication problems or other metadata directly via the socket reply, and the client could handle it immediately after connecting.

I expect it’d be relatively easy to implement. The interface would be an extra {:ok, reply, socket} case to the return type of connect/3, and an argument passed to the onOpen callback, both of which are backwards-compatible changes.

I haven’t seen others asking for this idea like I’ve seen others wanting to reply with a rejection reason, but I think it would still be generally useful. Not just for authentication issues like me, but I’m sure there are plenty of application-specific use cases for something like this, like replying with user metadata that the client didn’t know before joining.

This feature is my main suggestion and reason for making this post.

The only risk I can see with something like this is that being able to send data on a socket outside of a channel (even if it’s just a one-time reply) could make learning the distinction between sockets and channels more confusing. I can imagine people asking when to use socket replies and when to use channel replies. But this is minor.

Summary:
It’d be nice if it was possible to reply to a socket connection (maybe rejection reasons, but probably just accepted connections) with a payload.

Showing Posts 1 to 3

entone

entone

You should be able to utilize the HTTP response status for handling different connection errors. We currently use this for handling rate limiting vs auth errors.

skyqrose

skyqrose OP

I tried and I saw the HTTP response status appear in the dev tools network tab, but it didn’t appear in the Event passed to the callbacks. I wonder if that’s browser-dependent? I’m using Firefox. I did see the websocket status code but it was the same status code (I think it was 1006) for timeouts and all responses I sent.

steffend

steffend

Phoenix Core Team

One idea for having custom error handling would be to do a regular HTTP request using fetch instead of relying on the socket connect. You could do your regular authentication/authorization checks and then return any response you like. On success, you’d respond with a short-lived signed Phoenix.Token that you use for the socket connect. Therefore, when connecting, you can verify the token and skip the other checks. With that approach, the only case where the connect would fail (other than an attacker deliberately messing with tokens) is a network error.

— All posts loaded —

Where Next? Top

Trending in Proposals: Ideas Top

woylie
We are seeing a lot of warning logs like this: navigate event to "https://someurl" failed because you are redirecting across live_sessio...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews