Я тестирую каналы в Django 1.10 и настраиваю несколько пользователей.
Я попробовал создать декоратор login_required для него, который закрывает соединение, прежде чем выполнять его, чтобы гости не вошли в этот приватный сокет. Кроме того, после этого интегрированные модульные тесты проверяют, и они продолжают терпеть неудачу, потому что они продолжают позволять гостям (ошибки AnonymousUser повсюду).
Кроме того, иногда при входе в систему и выходе из нее сеанс не очищается, и он позволяет старому пользователю входить.
Декоратор:
def login_required_websocket(func):
"""
If user is not logged in, close connection immediately.
"""
@functools.wraps(func)
def inner(message, *args, **kwargs):
if not message.user.is_authenticated():
message.reply_channel.send({'close': True})
return func(message, *args, **kwargs)
return inner
Здесь потребительский код:
def ws_connect(message, slug):
message.reply_channel.send({ 'accept': True })
client = message.reply_channel
client.send(signal.message("Welcome"))
try:
# import pdb; pdb.set_trace()
Room.objects.get(name=slug)
except Room.DoesNotExist:
room = Room.objects.create(name=slug)
room.users.add(message.user)
room.turn = message.user.id
room.save()
story = Story(room=room)
story.save()
# We made sure it exists.
room = Room.objects.get(name=slug)
message.channel_session['room'] = room.name
# Check if user is allowed here.
if not room.user_allowed(message.user):
# Close the connection. User is not allowed.
client.send(Signal.error("User isn't allowed in this room."))
client.send({'close': True})
Странная вещь, когда комментирует всю логику между client.send(signal.message)) вперед, она работает просто отлично, а модульные тесты проходят (что означает, что гости заблокированы, а auth-код не запускается [следовательно, ошибки AnonymousUser]). Любые идеи?
Здесь также тесты:
class RoomsTests(ChannelTestCase):
def test_reject_guest(self):
"""
This tests whether the login_required_websocket decorator is rejecting guests.
"""
client = HttpClient()
user = User.objects.create_user(
username='test', password='password')
client.send_and_consume('websocket.connect',
path='/rooms/test_room', check_accept=False)
self.assertEqual(client.receive(), {'close': True})
def test_accept_logged_in(self):
"""
This tests whether the connection is accepted when a user is logged in.
"""
client = HttpClient()
user = User.objects.create_user(
username='test', password='password')
client.login(username='test', password='password')
client.send_and_consume('websocket.connect', path='/rooms/test_room')
Я подхожу к этому неправильно, и если да, то как мне это сделать (требуется auth) правильно?
EDIT: интегрированная система действий, чтобы что-то попробовать, похоже, что каналы Django просто не собирают какие-либо сеансы из HTTP.
@enforce_ordering
@channel_session_user_from_http
def ws_connect(message, slug):
message.reply_channel.send({'accept': True})
message.reply_channel.send(Action.info(message.user.is_authenticated()).to_send())
Просто возвращает false.
EDIT2: Я вижу, что он работает сейчас, я попытался изменить localhost на 127.0.0.1 и теперь он работает. Есть ли способ, чтобы он обнаруживал localhost как допустимый домен, чтобы он проходил через сеансы?
EDIT3: Оказывается, я нашел localhost vs 127.0.0.1 cookie issue haha. Чтобы не тратить деньги на награду, как бы вы лично реализовали auth login_required в сообщениях/каналах?
edit4: Пока я до сих пор не знаю, почему это не сработало, вот как я в конце концов изменил приложение вокруг проблемы:
Я создал систему действий. При входе в розетку сокет ничего не делает, пока вы не отправите ему действие AUTHENTICATE через JSON. Я разделял вход в действия в guest_actions и user_actions. После аутентификации он устанавливает сеанс, и вы можете использовать user_actions.