Несколько сбит с толку из-за того, что auth и сессии работают в Python / Django - PullRequest
0 голосов
/ 05 августа 2011

Я использую существующую базу данных для моего последнего проекта Django, поэтому, если я не изменю свои Модели или код авторизации Django, объединить их будет довольно сложно.

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

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

В функции входа в Django по умолчанию она назначает пользователя для request.user ... это каким-то образом сохраняется как переменная сеанса или просто передается в следующее представление? Если оно просто передается следующему представлению, то как аутентифицируются будущие запросы, не требуя дополнительных запросов входа?

Авторизованный логин Django по умолчанию ниже ..

def login(request, user):
    """
    Persist a user id and a backend in the request. This way a user doesn't
    have to reauthenticate on every request.
    """
    if user is None:
        user = request.user
    # TODO: It would be nice to support different login methods, like signed cookies.
    if SESSION_KEY in request.session:
        if request.session[SESSION_KEY] != user.id:
            # To avoid reusing another user's session, create a new, empty
            # session if the existing session corresponds to a different
            # authenticated user.
            request.session.flush()
    else:
        request.session.cycle_key()
    request.session[SESSION_KEY] = user.id
    request.session[BACKEND_SESSION_KEY] = user.backend
    if hasattr(request, 'user'):
        request.user = user
    user_logged_in.send(sender=user.__class__, request=request, user=user)

Я также пытался следовать user_logged_in.send (), который находится в django.dispatch.dispatcher.send, но я не совсем уверен, что он должен делать.

def send(self, sender, **named):
    """
    Send signal from sender to all connected receivers.

    If any receiver raises an error, the error propagates back through send,
    terminating the dispatch loop, so it is quite possible to not have all
    receivers called if a raises an error.

    Arguments:

        sender
            The sender of the signal Either a specific object or None.

        named
            Named arguments which will be passed to receivers.

    Returns a list of tuple pairs [(receiver, response), ... ].
    """
    responses = []
    if not self.receivers:
        return responses

    for receiver in self._live_receivers(_make_id(sender)):
        response = receiver(signal=self, sender=sender, **named)
        responses.append((receiver, response))
    return responses

По сути, я ищу, чтобы кто-то объяснил эффективный способ сохранения пользовательских данных сеанса в Python, который не зависит от инфраструктуры Django. Небольшой прогон аутентификации в Django тоже подойдет.

1 Ответ

11 голосов
/ 05 августа 2011

HTTP не имеет состояния;независимо от используемого сервера, платформы или языка, для HTTP-клиента не существует способа сказать «этот запрос является частью этого сеанса».Это часть дизайна HTTP.

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

Данные сеанса могут быть сериализованы и сохранены в самом файле cookie, но это небезопасно (секретная информация может быть подделана или подслушана) и неэффективно (занимает полосу пропускания, даже если отдельные байты бесполезны для клиента)и поэтому предпочтительным решением является использование непрозрачного (и даже лучше, одноразового) сеансового ключа, хранящегося в cookie, и веб-приложение будет хранить данные сеанса вне диапазона;либо в памяти, либо в файловой системе, либо в базе данных, либо в какой-либо другой опции.

django прозрачно заботится о большей части этого в «промежуточном программном обеспечении», модулях, которые модифицируют входящие запросы и исходящие ответы.Промежуточное программное обеспечение аутентификации прочитает cookie и проверит, представляет ли он вошедшего в систему пользователя, и, если да, добавит пользовательский объект в запрос;он также прикрепляет файлы cookie к ответам, когда пользователь входит в систему. Промежуточное программное обеспечение сеанса работает аналогичным образом, проверяя наличие файла cookie и считывая данные сеанса из любого места, где они были сохранены между запросами, а также извлекая данные сеанса из ответов и сохраняя их.наряду с установкой файла cookie для связи сеанса клиента с данными сеанса, которые он только что сохранил.

Поскольку обе эти функции полезны, независимы друг от друга (я склонен избегать сеансов, но обычно использую какой-тоаутентификация), они не зависят друг от друга.Сеансовая аутентификация реализуется аналогично сеансам, но аутентифицированные пользователи не сохраняются в «Сеансе», а сеансы не привязываются к «Аутентифицированному пользователю».

Вы можете так не думать, но система аутентификации django предназначена для расширения ;если у вас уже есть база данных действительных пользователей, с которыми вы хотите проходить аутентификацию, очень просто добавить новый auth backend, который аккуратно согласуется со стандартным приложением django auth (что означает, что вы также можете по очереди использовать другие приложения, которые зависят от него)).

...