#python #django #sockets #session #django-channels
#python #django #сокеты #сессия #django-каналы
Вопрос:
Я следил за этим руководством: Наконец, Django в реальном времени здесь: начните с Django Channels.
Я хотел расширить приложение, используя пользовательские объекты Django вместо handle
переменной. Но как я могу получить текущего пользователя из полученного пакета WebSocket в моей ws_recieve(message)
функции?
Я заметил, что csrftoken
и первые десять цифр sessionid
из пакета веб-сокета соответствуют обычному HTTP-запросу. Могу ли я получить от текущего пользователя эту информацию?
Для справки полученный пакет выглядит следующим образом:
{'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>}
Ответ №1:
Обновленный ответ в 2018 году через документы:
Чтобы получить доступ к пользователю, просто используйте self.scope[«user»] в вашем потребительском коде:
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
Ответ №2:
Примечание: Вопрос специфичен для Channels 1.x
и системы Django
сеансов, если вы здесь для Channels 2.x
way, пожалуйста, прочитайте документы по ссылке ниже, в них более чем ясно, как это сделать, Channels 1.x
документы сбивали с толку некоторых людей (включая меня), вот почему этот вопрос и другие были сделаныв Channels 2.x
документах совершенно ясно, как этого добиться:
https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication
Каналы 1.x:
Вы можете получить доступ к user
http_session
своим атрибутам и message
, изменив декораторы в consumers.py
соответствии с документами:
Вы получаете доступ к обычному сеансу Django пользователя, используя
http_session decorator
— это дает вамmessage.http_session
атрибут, который ведет себя так же, какrequest.session
. Вы можете пойти еще дальше и использоватьhttp_session_user
which предоставитmessage.user
атрибут, а также атрибут сеанса.
итак consumers.py
, файл в примере должен стать следующим:
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):
...
...
Обратите внимание на изменение декораторов.
Кроме того, я предлагаю вам ничего не строить на этом примере
для получения более подробной информации смотрите: https://channels.readthedocs.io/en/1.x/getting-started.html#authentication
Комментарии:
1. Спасибо за помощь! Если я правильно понимаю
channel_session_user
, добавляетmessage.user
атрибут, но мне все равно нужно будет использоватьchannel_session
для сохранения других данных, верно?2. да, документы говорят об этом:
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.
3. ссылка не работает: channels.readthedocs.io/en/stable /…