Понимание каналов Django - QueryAuthMiddleware - PullRequest
0 голосов
/ 07 ноября 2018

Как написать пользовательскую аутентификацию пользователя, который подключается к чату по протоколу ws: //? Этот пользователь находится на другой стороне приложения Django, он является мобильным пользователем, подключающим websocket через ws: // из мобильного приложения. Я пытался протестировать веб-сокет с расширением Chrome, он не мог подключиться к моему веб-сокету. Я думаю, что это было из-за аутентификации.

В документах по каналам Django написано:

Если у вас есть специальная схема аутентификации, вы можете написать собственное промежуточное программное обеспечение, чтобы проанализировать детали и поместить пользовательский объект (или любой другой нужный вам объект) в вашу область. оборачивает это, чтобы возвратить другое приложение ASGI. Большую часть проверки подлинности можно выполнить только в области, поэтому все, что вам нужно, это переопределить начальный конструктор, который принимает область, а не сопрограмму, запускающую событие. Вот простой пример промежуточного программного обеспечения, которое просто извлекает идентификатор пользователя из строки запроса и использует его: Те же принципы могут применяться для аутентификации по не-HTTP протоколам; например, вы можете использовать чье-либо имя пользователя чата из протокола чата, чтобы превратить его в пользователя.

from django.db import close_old_connections

class QueryAuthMiddleware:
    def __init__(self, inner):
        # Store the ASGI application we were passed
        self.inner = inner

    def __call__(self, scope):
        # Look up user from query string (you should also do things like
        # check it's a valid user ID, or if scope["user"] is already populated)
        user = User.objects.get(id=int(scope["query_string"]))
        close_old_connections()
        # Return the inner application directly and let it run everything else
        return self.inner(dict(scope, user=user))

Какой запрос мне нужно сделать? Я ничего не знаю об этом пользователе, на самом деле он анонимный.

Помогите мне, пожалуйста.

1 Ответ

0 голосов
/ 11 ноября 2018

В этом примере кода вам, вероятно, придется открыть соединение с веб-сокетом с помощью:

ws://SERVER:PORT/PATH?1

Все после ? является строкой запроса. В вашем примере кода строка query_string должна быть идентификатором пользователя, например, 1.

Вы можете изменить код, чтобы использовать разные строки запроса. Например, вы можете использовать:

from urllib.parse import parse_qs
from django.db import close_old_connections

class QueryAuthMiddleware:
    def __init__(self, inner):
        # Store the ASGI application we were passed
        self.inner = inner

    def __call__(self, scope):
        # Look up user from query string (you should also do things like
        # check it's a valid user ID, or if scope["user"] is already populated)

        query_string = parse_qs(self.scope['query_string'])
        if b'user_id' in query_string:
            user = User.objects.get(id=int(query_string[b'user_id'][0]))
            close_old_connections()
        else:
            user = AnonymousUser
        # Return the inner application directly and let it run everything else
        return self.inner(dict(scope, user=user))

Теперь вы можете использовать этот URI:

ws://SERVER:PORT/PATH?user_id=1

Вы должны убедиться, что пользователь с идентификатором существует в базе данных. Вы также должны написать реальный код авторизации. Каждый пользователь может подключиться к этому приложению с произвольным идентификатором пользователя. Нет пароля или авторизационного токена.

...