使用django渠道allowed_hosts_only与基于类的消费者

时间:2017-08-14 02:49:11

标签: python django django-channels

the docs开始,allowed_hosts_only是一个装饰器,以确保连接源位于settings.ALLOWED_HOSTS。但是我很难将它应用于基于类的消费者。 applying decorators部分介绍了如何在类中添加装饰器:

from channels.generic.websockets import JsonWebsocketConsumer
from channels.security.websockets import allowed_hosts_only

class MyConsumer(JsonWebsocketConsumer):
    ...
    def get_handler(self, *args, **kwargs):
        handler = super(MyConsumer, self).get_handler(*args, **kwargs)
        return allowed_hosts_only(handler) # just 'return handler' works

这是我得到的错误:

[2017/08/14 02:32:05] WebSocket HANDSHAKING / [123.123.123.123:12345]
[2017/08/14 02:32:05] WebSocket DISCONNECT / [123.123.123.123:12345]
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/threading.py", line 804, in __bootstrap_inner
    self.run()
  File "/home/user/env/lib/python2.7/site-packages/channels/management/commands/runserver.py", line 175, in run
    worker.run()
  File "/home/user/env/lib/python2.7/site-packages/channels/worker.py", line 123, in run
    raise ValueError("You cannot DenyConnection from a non-websocket.connect handler.")
ValueError: You cannot DenyConnection from a non-websocket.connect handler.

我应该如何使用基于类的消费者验证连接来源?

我认为AllowedHostsOnlyOriginValidator可能是混音,但来源只有allowed_hosts_only = AllowedHostsOnlyOriginValidator

1 个答案:

答案 0 :(得分:0)

您已检查频道是否为websocket。您可以通过检查Channel的名称来执行此操作。您在Message上找到该实例。当名称是 websocket.connect 时,您使用allowed_hosts_only装饰器装饰处理程序。

这就是get_handler应该是这样的:

  def get_handler(self, message, **kwargs):
    handler = super(KioskConsumer, self).get_handler(message, **kwargs)
    if self.message.channel.name == "websocket.connect":
      handler = allowed_hosts_only(handler)
    return handler