对Python/Django中auth和会话的工作方式有些困惑

对Python/Django中auth和会话的工作方式有些困惑,python,django,session,authentication,login,Python,Django,Session,Authentication,Login,我正在为我最新的Django项目使用一个现有的数据库,因此除非我更改我的模型或Django auth代码,否则将很难将两者合并 我计划只编写我自己的身份验证应用程序,而不是搞乱现有的身份验证后端 无论如何,我以前的所有身份验证应用程序都是用PHP编写的,基本上我只是将所有内容都放入会话变量中,并在每个页面上验证它们。。。这就是我有点困惑的地方。当一个用户通过身份验证/登录时,整个用户都会被添加到会话中,但我不知道这是在哪里发生的,或者是如何发生的 在默认的Django登录函数中,它将用户分配到r

我正在为我最新的Django项目使用一个现有的数据库,因此除非我更改我的模型或Django auth代码,否则将很难将两者合并

我计划只编写我自己的身份验证应用程序,而不是搞乱现有的身份验证后端

无论如何,我以前的所有身份验证应用程序都是用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)
我还尝试跟踪django.dispatch.dispatcher.send中的用户_logged_in.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身份验证也不错。

HTTP是无状态的;无论使用哪种服务器、哪种框架或语言,HTTP客户端都没有内在的方式来表示此请求是该会话的一部分。这是HTTP设计的一部分

因此,会话始终是web应用程序的一个功能;由web应用程序框架支持或在应用程序本身中实现。从无状态协议创建有状态会话的最常用方法是使用cookie;客户端将应服务器的请求存储cookie,并在将来的请求中将这些cookie返回给该服务器

会话数据可以序列化并存储在cookie本身中,但这两种情况都是不安全的,秘密信息可能被伪造或窃听,并且效率低下,占用带宽,即使单个字节对客户端没有任何用处,因此首选解决方案是使用不透明甚至更好的一次性会话密钥存储在cookie中,web应用程序将在带外存储会话数据;在内存、文件系统、数据库后端或其他一些选项中

django在中间件(修改传入请求和传出响应的模块)中透明地解决了大部分问题。auth中间件将读取一个cookie并检查它是否表示登录的用户,如果是,则向请求添加一个用户对象;当用户登录时,它还会将cookie附加到响应中。会话middlware以类似的方式工作,检查cookie,从请求之间存储会话数据的任何位置读取会话数据,还从响应中获取会话数据并存储它们,同时设置cookie以将客户端的会话与其刚刚存储的会话数据相关联

由于这两个功能都是有用的,相互独立,我倾向于避免会话,但通常使用某种身份验证,它们互不依赖。类似会话的身份验证以与会话类似的方式实现,但是经过身份验证的用户不会存储在会话中,会话也不会附加到经过身份验证的用户

您可能不这么认为,但django的身份验证系统是;如果您已经有了一个有效用户的数据库,您希望对其进行身份验证,那么添加一个新的auth后端非常简单,它与标准的django auth应用程序完美地吻合,这意味着您还可以依次使用依赖它的其他应用程序