Phoenix server side code organisation for channels

I’m currently working on an application where the clients will be single page applications or mobile apps. Working environment is Phoenix 1.3.0 on server side and Javascript on client side. I have some some architectural and security questions: as this is my first real Phoenix application, I have made some choices so far and I’m wondering if they are the good ones. (NB: this was posted on Stackoverflow some days ago by got no reply).

As the client apps will be mobile or SPA, the main communication method is channels through websockets. Yet, as long as the user is not logged in, client will communicate with the server by exchanging JSON messages on HTTP. Basically 2 API will be implemented that way : the register API and the login API. Once the user is logged in, the login API handler returns a random key encapsulated inside a Token and the client immediately connects a socket and joins a Channel.

Q1. Where to authentify the user’s websocket connection?

Basically, the Token will be verify()-ed, and the encapsulated key will be checked against the one that had been sent by login API. This can be done in UserSocket.connect() or in the UserChannel.join() function in the channel management module or even in both : Token verification can be done in connect() and user key verification in join(). Is there any preferred place to do this?

Q2: Where to manage user state representation ?

In the first place I intended to create an Agent, a custom UserAgent module to handle all user state and to implement all the functions for handling API that apply on the users. The UserAgent would be registered in the Registry and identified by the very key send back by the login handler. The intent was to de-correlate incoming and outgoing message handling that takes place in UserChannel from the management of the user itself.

This makes me run into some issues like:

  • I’m too early in the development to have any real issue, yet I believe that the UserAgent may not run on the same node than the one on which the websocket is connected. The Registry being local, how would the Channel handler find the right UserAgent? Is implementing a kind of distributed registry an option ?

  • For every user, there would be two permanent processes : the channel chandler and the agent. It’s not because the VM is able to handle many of them that one might waste resources without a good reason…

The other way to proceed is to represent the state of the user as a fielf in the assigns of the socket. It doesn’t look very clean… What would be your advise ?

Q3: Is the transfer of identifiers secure

In all cases some kind of identifier needs to be transfered upon successful login to the client and then back to the server in order to join the channel. I understand Tokens are signed but not encrypted. Is the transfer of identifiers safe as they are keys to access user data in the system? What about Guardian?