shosti

shosti

Check for 403 response on socket client?

I have a socket/channel setup with some custom authentication logic. If the authentication fails, it shows an error message to the user (so they can fix the problem). Right now this is handled at the channel level–basically all socket connections are accepted, but only properly authenticated sockets can join particular channels.

I’d prefer to move auth checking to the socket level, so unauthenticated connections get refused with a 403 (that would prevent accidental and/or malicious unauthed connections from holding unnecessary socket connections). The problem I’m running into: socket authentication failures seem to be handled the same way as “normal” connection failures by the client (triggering onClose and onError with generic close events, starting retries, etc.).

So my question: is there any way to have custom handling for socket authentication errors on the client side? I’d like “normal” connection failures to use the default behavior (retries, etc.) but authentication failures to not retry and instead alert the user. Thanks in advance!

Marked As Solved

josevalim

josevalim

Creator of Elixir

If I remember correctly, it is not possible to do so because browsers do not provide enough information to the client in a way we can inform what went wrong, unfortunately. :frowning:

Also Liked

GregMefford

GregMefford

I was unwilling to accept that this is impossible, so I’ve come up with the following hack that works to resolve the issue of a Phoenix Socket that has an expired authentication token, causing it to return a 403 when the client tries to reconnect. This happens, for example, when the user has left a page open for hours on end, so the token is expired, but the Phoenix Channel client is still trying to reconnect and the page itself is still loaded in the browser, so it has no idea that its token is expired.

Each time it tries and fails to connect, it generates an event that can be captured with a socket.onError callback. The problem is that this event doesn’t have any useful information in it about why the connection failed. We can see that the reason is because the connection 403ed in the Chrome dev tools, but JavaScript can’t see that error message. The hack is to have a callback that makes an AJAX call to the server, being sure to send credential cookies like you normally would, and check whether it gets redirected to your login page. This obviously assumes that the AJAX call you make would get redirected if you’re not logged in, and would not get redirected if you’re already logged in.

In this case, I’m just reloading the page when I detect this condition (which will cause me to get redirected to login again), but you could do whatever you need to do in JavaScript-land.

Pardon my terrible JavaScript; hopefully you can find the meaning beneath the madness.

const reloadOnRedirect = () => {
  fetch('/', {credentials: 'same-origin'})
    .then((response) => { if (response.redirected) window.location.reload() });
}

// Normal Socket setup code ...

socket.onError(reloadOnRedirect);
socket.connect
Kabie

Kabie

Yes, I understand that. However, clients other than a browser may have access to that, which is my case.

I can write a Transport replacing Phoenix.Transports.WebSocket, but I can only returns {:ok, socket} or :error in connect:

https://github.com/phoenixframework/phoenix/blob/5d90892e32cae195b8235fb921666cd016fef111/lib/phoenix/socket/transport.ex#L179

I’m asking can we allow a {:error, reason} case here, so a Transport can leverage that.

Stingray

Stingray

The same issue. Any ideas?

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

Other popular topics Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement