需要在Django Channels套接字中登录?

Ser*_*iaz 13 python sockets django django-channels daphne

我正在尝试Django 1.10中的频道并建立一些消费者.

我尝试为它创建一个login_required装饰器,在执行它之前关闭连接以防止guest虚拟机进入此私有套接字.之后还集成了单元测试以测试它并且它们一直在失败,因为它一直让访客进入(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
Run Code Online (Sandbox Code Playgroud)

这是消费者代码:

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})
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当注释掉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')
Run Code Online (Sandbox Code Playgroud)

我是否接近这个错误,如果我是,我该怎么做(需要auth)呢?

编辑:集成一个动作系统来尝试一些东西,看起来像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())
Run Code Online (Sandbox Code Playgroud)

只返回false.

EDIT2:我现在看到它有效,我尝试将localhost更改为127.0.0.1,结果现在可以使用了.有没有办法让它检测localhost作为一个有效的域,以便它通过会话端口?

编辑3:结果我发现localhost vs 127.0.0.1 cookie问题哈哈.为了不浪费赏金,您将如何亲自在消息/频道中实现auth login_required?

edit4:虽然我仍然不知道为什么这个东西不起作用,但这是我最终改变我的应用程序的问题:

我创建了一个动作系统.进入时,套接字不执行任何操作,直到您通过JSON向其发送AUTHENTICATE操作.我在guest_actions和user_actions中分离了登录的操作.经过身份验证后,它会设置会话,您可以使用user_actions.

Chr*_*aro 2

Django Channels 已经支持会话身份验证:

# In consumers.py
from channels import Channel, Group
from channels.sessions import channel_session
from channels.auth import channel_session_user, channel_session_user_from_http

# Connected to websocket.connect
@channel_session_user_from_http
def ws_add(message):
    # Accept connection
    message.reply_channel.send({"accept": True})
    # Add them to the right group
    Group("chat-%s" % message.user.username[0]).add(message.reply_channel)

# Connected to websocket.receive
@channel_session_user
def ws_message(message):
    Group("chat-%s" % message.user.username[0]).send({
        "text": message['text'],
    })

# Connected to websocket.disconnect
@channel_session_user
def ws_disconnect(message):
    Group("chat-%s" % message.user.username[0]).discard(message.reply_channel)
Run Code Online (Sandbox Code Playgroud)

http://channels.readthedocs.io/en/stable/getting-started.html#authentication

  • 这并不能回答我的问题。我建议你再读一遍这个问题。我知道它支持身份验证,我想阻止仅对来宾进行通道访问,并且我正在寻找最佳的异步兼容方式来执行此操作。 (2认同)