简体   繁体   中英

Using django channels allowed_hosts_only with class based consumers

From the docs , allowed_hosts_only is a decorator to make sure the connection origin is in settings.ALLOWED_HOSTS . However I'm having difficulty applying it to a class based consumer. The applying decorators sections explains how to add decorators to the class:

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

This is the error I get:

[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.

How should I be validating the connection origin with a class based consumer?

I thought AllowedHostsOnlyOriginValidator might be a mixin, but the source simply has allowed_hosts_only = AllowedHostsOnlyOriginValidator .

You have check the channel for being a websocket. You can do this by checking the name of the Channel . You find that instance on the Message . When the name is websocket.connect you decorate the handler with the allowed_hosts_only decorator.

This is how your get_handler should look like:

  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM