Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add callback in PhoenixSocket to update _options when socket closes and try to reconnect #97

Open
jaybe78 opened this issue Nov 2, 2024 · 2 comments

Comments

@jaybe78
Copy link

jaybe78 commented Nov 2, 2024

Hey Guys,

When I'm connecting to a socket, on the server side, I have to verify the passed jwt is valid.
My signed JWT are mostly only valid a couple of minutes.

def connect(_params, socket, connect_info) do
    result = verify_jwt(_params["jwt"])

    case result do
      {:ok,  %{ "email" => email}} ->
        socket =
          assign(socket, :user_id, email)
          |> assign(:username, _params["username"])

        {:ok, socket}

      {:error, :token_expired} ->
         {:error, reason: result}
    end
  end

on the client side, I pass a jwt to PhoenixSocket to connect:

PhoenixSocketOptions(
      params: {
        "username": globalCubit.state.profile!.username,
        "jwt": credentials!.jwtToken,
        "user_pk": globalCubit.state.profile!.email,
      },
    );

So the issue is that, if for any reason the socket closes, it will try to reconnect using the JWT passed the first time which obviously might be expired by then.

So, I tried to find a way to update the _options but it's not exposed publicly

_options needs to be updated so that when connect is called the _buildMountPoint contaiuns the latestJWT

_mountPoint = await _buildMountPoint(_endpoint, _options);

So I'm thinking there should be a setter for

PhoenixSocketOptions _options

That way in our own implementation. when the "close" stream event occurs we can update any credentials required to connect to the socket

Just did a quick test and this is working.

class PhoenixSocket {

...
void set options(PhoenixSocketOptions options) {
    _options = options;
  }

)


_socket = socket.connect();
_socket?.closeStream.listen((event) {
   _socket.options = {new options with updated jwt}
});

EDIT: the above is not good enough because when socket connect fails, it gets directly to delayReconnect, so even if the jwt is updated afterwards (when its gets into the close event) it would still be the previous one.

So in addition to PhoenixOptions, why not also add an option for an async callback getSocketOptions

I tested the following and it works well.

PhoenixSocket(
...
    PhoenixSocketOptions? socketOptions,
    Future<PhoenixSocketOptions> Function()? getSocketOptions,

    /// The factory to use to create the WebSocketChannel.
    WebSocketChannel Function(Uri uri)? webSocketChannelFactory,
  })  : _endpoint = endpoint,
        ...{
    _options = socketOptions ?? PhoenixSocketOptions();
    _getSocketOptions = getSocketOptions != null ? getSocketOptions: () async => _options;

    late Future<PhoenixSocketOptions> Function() _getSocketOptions;

void _connect(Completer<PhoenixSocket?> completer) async {
   ...

    final socketOpts = await _getSocketOptions();
    _mountPoint = await _buildMountPoint(_endpoint, socketOpts);

That way in your getSocketOptions, you could for example always get the latest jwt when you refresh it using refreshJWT.

@jaybe78 jaybe78 changed the title Exposing public function in PhoenixSocket class to rebuild _buildMountPoint when socket closes and tries to reconnect Exposing setter in PhoenixSocket class to update _options when socket closes and tries to reconnect Nov 2, 2024
@jaybe78 jaybe78 changed the title Exposing setter in PhoenixSocket class to update _options when socket closes and tries to reconnect Add callback inPhoenixSocket to update _options when socket closes and tries to reconnect Nov 3, 2024
@matehat
Copy link
Member

matehat commented Nov 4, 2024

Hi @jaybe78, thanks for the write up. Would you feel comfortable making a PR with the changes you propose?

@jaybe78 jaybe78 changed the title Add callback inPhoenixSocket to update _options when socket closes and tries to reconnect Add callback in PhoenixSocket to update _options when socket closes and try to reconnect Nov 4, 2024
@jaybe78
Copy link
Author

jaybe78 commented Nov 4, 2024

Hey @matehat

Yes definitely.
Will do that tomorrow

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants