Search code examples
djangotornado

Tornado with Django authentication


Here's my idea:

  • have a Django Website that receives / send JSON information so that I can create a JavaScript client for a Webbrowser, or a Unity / UE client
  • I want a new functionality only for Unity / UE client: realtime chat.

I'd like to use a tornado server on a specific port, let's say 8666.

Here's what I've done so far:

  • authenticate on the Django web site
  • make everything work on the Django web site

Now I'd like the client to connect to the port 8666 (pure TCP) and to send something (maybe his session cookie or something else) so that I can see on the tornado web server whether the client is authenticated, and look in the database to find out which other mates are connected too on the tornado webserver, so that when this client writes something, I can dispatch his message to all other "concerned" connected clients.

I didn't find any documentation about that. Do you know how to handle this? Any example, or if I'm not on the right track what should I do then?


Solution

  • If your Tornado process runs on the same domain as your Django application, the session cookie will be sent by the browser upon websocket handshake, and accessible through the WebSocketHandler.get_cookie() method.

    Here is an example, assuming a global variable CLIENTS keeping track of connected authentified clients:

    def open(self):
        """Authenticate client based on session cookie, add broadcast notification"""
        session_id = self.get_cookie('sessionid')
        if not session_id:
            self.close()
        self.authenticate_user(session_id)
        if self.user is None:
            self.close()
        self.CLIENTS.append(self)
        self.notify_all_clients()
    
    def authenticate_user(self, session_id):
        """Retrieve User instance associated to the session key."""
        session = SessionStore(session_key=session_id)
        user_id = session.get('_auth_user_id')
        if user_id is None:
            return
        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            self.close()
        else:
            self.user = user
    

    Hope this helps!

    Edit:

    Note that to be able to use the Django ORM, you must set the DJANGO_SETTINGS_MODULE environment variable to your app's settings module path (e.g. 'myapp.settings', making sure it can be found through sys.path) and then call setup() as explained in the Django docs.