When using django channels, I have a long-running websocket connection. My users may become logged out due to their session expiring while this connection is still active. This causes sporadic behavior where HTTP requests don't work, because they're not authenticated, but the websocket is still sending and receiving data like nothing is wrong.
The Django Channels docs say:
If you are using a long running consumer, websocket or long-polling HTTP it is possible that the user will be logged out of their session elsewhere while your consumer is running. You can periodically use get_user(scope)
to be sure that the user is still logged in.
However, this doesn't work. When I call the following code I'm able to see that Django Channels believes the user is still authed.
user = async_to_sync(get_user)(self.scope)
print(user.is_authenticated)
What is the correct way to check if a user is still authenticated in a Django Channels websocket consumer? This GitHub issue touches on the issue but doesn't have a good solution
Websocket consumer as follows:
class GUIConsumer(WebsocketConsumer):
def connect(self):
async_to_sync(self.channel_layer.group_add)(
GROUP_NAME, self.channel_name)
user = self.scope.get('user')
if user and user.has_perm('auth.can_access_ui'):
self.accept()
else:
self.accept()
self.close()
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
GROUP_NAME, self.channel_name)
def data(self, event):
publisher_type = event.get('publisher')
data = event.get('data')
self.send(text_data=json.dumps({publisher_type: data})
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json.get('message', '')
if message == "---ping---":
self.send(text_data=json.dumps({'heartbeat': '---pong---'}))
question from:
https://stackoverflow.com/questions/65907597/django-channels-long-running-consumer-authentication-issues 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…