How to get current user from a Django Channels web socket packet?
Solution 1
Note: The question is specific to Channels 1.x
and the Django
session system, if you're here for Channels 2.x
way, please read the docs from the link below, they're more than clear on how to do this, the Channels 1.x
docs were confusing for some people (including me), this is why this question and others were made, the Channels 2.x
docs are crystal clear on how to achieve this:
https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication
Channels 1.x:
You can get access to a user
and http_session
attributes of your message
by changing the decorators in consumers.py
to match the docs:
You get access to a user’s normal Django session using the
http_session decorator
- that gives you amessage.http_session
attribute that behaves just likerequest.session
. You can go one further and usehttp_session_user
which will provide amessage.user
attribute as well as the session attribute.
so the consumers.py
file in the example should become the following:
from channels.auth import http_session_user, channel_session_user, channel_session_user_from_http
@channel_session_user_from_http
def ws_connect(message):
...
...
@channel_session_user
def ws_receive(message):
# You can check for the user attr like this
log.debug('%s', message.user)
...
...
@channel_session_user
def ws_disconnect(message):
...
...
Notice the decorators change.
Also, i suggest you don't build anything upon that example
for more details see: https://channels.readthedocs.io/en/1.x/getting-started.html#authentication
Solution 2
Updated answer in 2018 via the docs:
To access the user, just use self.scope["user"] in your consumer code:
class ChatConsumer(WebsocketConsumer):
def connect(self, event):
self.user = self.scope["user"]
def receive(self, event):
username_str = None
username = self.scope["user"]
if(username.is_authenticated()):
username_str = username.username
print(type(username_str))
#pdb.set_trace() # optional debugging
Related videos on Youtube
user1577434
Updated on September 16, 2022Comments
-
user1577434 about 1 year
I was following this tutorial: Finally, Real-Time Django Is Here: Get Started with Django Channels.
I wanted to extend the app by using Django User objects instead of the
handle
variable. But how can I get the current user from the received WebSocket packet in myws_recieve(message)
function?I noticed that both the
csrftoken
and the first ten digits ofsessionid
from the web socket packet match a normal HTTP request. Can I get the current user with this information?For reference the received packet looks like this:
{'channel': <channels.channel.Channel object at 0x110ea3a20>, 'channel_layer': <channels.asgi.ChannelLayerWrapper object at 0x110c399e8>, 'channel_session': <django.contrib.sessions.backends.db.SessionStore object at 0x110d52cc0>, 'content': {'client': ['127.0.0.1', 52472], 'headers': [[b'connection', b'Upgrade'], [b'origin', b'http://0.0.0.0:8000'], [b'cookie', b'csrftoken=EQLI0lx4SGCpyTWTJrT9UTe1mZV5cbNPpevmVu' b'STjySlk9ZJvxzHj9XFsJPgWCWq; sessionid=kgi57butc3' b'zckszpuqphn0egqh22wqaj'], [b'cache-control', b'no-cache'], [b'sec-websocket-version', b'13'], [b'sec-websocket-extensions', b'x-webkit-deflate-frame'], [b'host', b'0.0.0.0:8000'], [b'upgrade', b'websocket'], [b'sec-websocket-key', b'y2Lmb+Ej+lMYN+BVrSXpXQ=='], [b'user-agent', b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) ' b'AppleWebKit/602.1.50 (KHTML, like Gecko) Version' b'/10.0 Safari/602.1.50'], [b'pragma', b'no-cache']], 'order': 0, 'path': '/chat-message/', 'query_string': '', 'reply_channel': 'websocket.send!UZaOWhupBefN', 'server': ['127.0.0.1', 8000]}, 'reply_channel': <channels.channel.Channel object at 0x110ea3a90>}
-
user1577434 about 7 yearsThanks, for the help! If I understand correctly
channel_session_user
addsmessage.user
attribute, but I would still need to usechannel_session
to persist other data right? -
HassenPy about 7 yearsyes, the docs say this:
Channels provides a channel_session decorator for this purpose - it provides you with an attribute called message.channel_session that acts just like a normal Django session.
-
Scott Skiles over 5 yearslink is broken: channels.readthedocs.io/en/stable/…