问个DJANGO的 用户登录问题~

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问个DJANGO的 用户登录问题~相关的知识,希望对你有一定的参考价值。

一般在使用了django提供的session组件了以后,session可以设置有效时间,即使关闭浏览器下次打开依然可进入。
那是否说明我可以不使用cookies来判断登录,直接使用session这个机制?
这样是不是很不安全,那大家平时在做的时候是怎么处理的?
我没用django的auth组件是为了多学习,不要给我推荐这个~~

参考技术A session里面保存了cookies地址了吧追问

可以说详细点嘛? 是不是说用session可以直接代替cookies了,然后关闭浏览器再打开也能照常进入个人页面了?

追答

咨询了下我们这专门做登陆的朋友,可以直接替代的

Django:用户登录时发出信号?

【中文标题】Django:用户登录时发出信号?【英文标题】:Django: signal when user logs in? 【发布时间】:2010-12-31 17:19:28 【问题描述】:

在我的 Django 应用程序中,我需要在用户登录时开始运行一些周期性的后台作业,并在用户注销时停止运行它们,所以我正在寻找一种优雅的方式来

    收到有关用户登录/注销的通知 查询用户登录状态

在我看来,理想的解决方案是

    每个django.contrib.auth.views.login... views.logout发送的信号 一种方法django.contrib.auth.models.User.is_logged_in(),类似于... User.is_active()... User.is_authenticated()

Django 1.1.1 没有这个,我不愿意修补源代码并添加它(反正不知道该怎么做)。

作为一个临时解决方案,我在 UserProfile 模型中添加了一个 is_logged_in 布尔字段,该字段默认清除,在用户第一次点击登录页面时设置(由 LOGIN_REDIRECT_URL = '/' 定义)并在后续查询要求。我将它添加到 UserProfile 中,因此我不必仅为该目的从内置 User 模型中派生和自定义。

我不喜欢这个解决方案。如果用户明确点击注销按钮,我可以清除标志,但大多数时候,用户只是离开页面或关闭浏览器;在这些情况下清除标志对我来说似乎并不简单。此外(不过,这是对数据模型清晰度的挑剔),is_logged_in 不属于 UserProfile,而是属于 User 模型。

谁能想到替代方法?

【问题讨论】:

请考虑选择一个新的答案。鉴于 1.3 中添加的信号,当前接受的选择是一个非常糟糕的选择。 你是对的;更改了接受的答案。 【参考方案1】:

除了@PhoebeB 答案: 你也可以像这样使用@receiver 装饰器:

from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver

@receiver(user_logged_in)
def post_login(sender, user, request, **kwargs):
    ...do your stuff..

如果您将其放入应用程序目录中的signals.py,则将其添加到apps.py

class AppNameConfig(AppConfig):
    ...
    def ready(self):
        import app_name.signals

【讨论】:

【参考方案2】:

对此的快速解决方案是,在您的应用程序的 _ _ init _ _.py 中放置以下代码:

from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver


@receiver(user_logged_in)
def on_login(sender, user, request, **kwargs):
    print('User just logged in....')

【讨论】:

【参考方案3】:

你可以使用这样的信号(我把我的放在models.py中)

from django.contrib.auth.signals import user_logged_in


def do_stuff(sender, user, request, **kwargs):
    whatever...

user_logged_in.connect(do_stuff)

请参阅 django 文档:https://docs.djangoproject.com/en/dev/ref/contrib/auth/#module-django.contrib.auth.signals 和此处http://docs.djangoproject.com/en/dev/topics/signals/

【讨论】:

既然 Django 1.3 提供了这些信号,它是一个比包装登录/注销调用更好的解决方案。这也意味着,如果您设置了新的登录方式——例如,Facebook/Twitter/OpenID 登录——它们仍然可以使用。 而不是将其放在models.py 中,我建议将代码放在signals.py 中并自动将其导入模块的__init__.py 文件中。 如何使用此信号在登录和注销时运行 javascript?【参考方案4】:

一种选择可能是用您自己的包装 Django 的登录/注销视图。例如:

from django.contrib.auth.views import login, logout

def my_login(request, *args, **kwargs):
    response = login(request, *args, **kwargs)
    #fire a signal, or equivalent
    return response

def my_logout(request, *args, **kwargs):
    #fire a signal, or equivalent
    return logout(request, *args, **kwargs)

然后您在代码中使用这些视图而不是 Django 的,瞧。

关于查询登录状态,如果您可以访问请求对象,则非常简单;只需检查请求的用户属性,看看他们是注册用户还是匿名用户,然后宾果游戏。引用Django documentation:

if request.user.is_authenticated():
    # Do something for logged-in users.
else:
    # Do something for anonymous users.

如果您无权访问请求对象,那么确定当前用户是否已登录将很困难。

编辑:

不幸的是,您将永远无法获得User.is_logged_in() 功能 - 这是 HTTP 协议的限制。但是,如果您做出一些假设,您可能会接近您想要的。

首先,您为什么不能获得该功能?好吧,您无法区分是关闭浏览器还是在获取新页面之前在页面上花费了一段时间。当有人真正离开网站或关闭浏览器时,无法通过 HTTP 判断。

所以这里有两个不完美的选择:

    使用 Javascript 的 unload 事件来捕捉用户何时离开页面。但是,您必须编写一些仔细的逻辑,以确保当用户仍在浏览您的网站时,您不会退出该用户。 每当用户登录时触发注销信号,以确保安全。还要创建一个经常运行以清除过期会话的 cron 作业——当过期会话被删除时,检查会话的用户(如果它不是匿名的)没有更多的活动会话,在这种情况下你会触发注销信号。

这些解决方案杂乱无章,并不理想,但不幸的是,它们是您能做的最好的。

【讨论】:

这仍然没有解决“大多数时候,用户只是离开页面或关闭浏览器”的情况。 感谢您的回答,当然包装登录/注销可以让我免于修补源代码,我自己也应该这样做。不过稍微更正一下:如果在调用 login 之前在 my_login 中发送了信号,则用户在信号处理程序中仍然是匿名的。更好(不要认为这会被正确格式化): def my_login(request): response = login(request) #fire a signal, or equivalent return response 另外,我已经在使用 is_authenticated,我只是觉得我需要比那更多的。不过,到目前为止,我在数据模型中的新 is_logged_in 部分尚未使用。 好点。我想我并没有真正很好地解决is_logged_in 的问题(在那里道歉,我想我没有很好地阅读这篇文章),但我已经更新了答案以提供我能提供的帮助在那个区域。不幸的是,这是一个不可能的问题。【参考方案5】:

推断注销,而不是让他们明确点击按钮(没有人这样做),意味着选择相当于“注销”的空闲时间量。 phpMyAdmin 使用默认值 15 分钟,一些银行网站只需 5 分钟。

实现这一点的最简单方法是更改​​ cookie 的生命周期。您可以通过指定settings.SESSION_COOKIE_AGE 为您的整个站点执行此操作。或者,您可以使用HttpResponse.setcookie() 在每个用户的基础上(基于任意一组标准)更改它。您可以通过创建自己的 render_to_response() 版本并设置每个响应的生命周期来集中此代码。

【讨论】:

【参考方案6】:

唯一可靠的方法(也检测用户何时关闭浏览器)是每次用户加载页面时更新一些 last_request 字段。

如果用户打开了一个页面,您还可以有一个周期性的 AJAX 请求,该请求每 x 分钟 ping 一次服务器。

然后有一个后台作业获取最近用户的列表,为他们创建作业,并清除该列表中不存在的用户的作业。

【讨论】:

这是衡量用户是否登录的最佳方式。您基本上必须保留一个登录用户名册并检查他们的最后一次访问是什么并决定超时。如果您将超时设置为 10 分钟左右,然后让每个网页在页面处于活动状态时每 5 分钟左右调用一次 Ajax 请求,这应该会保持最新状态。【参考方案7】:

粗略的想法 - 您可以为此使用中间件。该中间件可以处理请求并在请求相关 URL 时触发信号。当给定动作实际成功时,它还可以处理响应和触发信号。

【讨论】:

以上是关于问个DJANGO的 用户登录问题~的主要内容,如果未能解决你的问题,请参考以下文章

django登录用户,成功登录后用户停留在同一页面

登录后 Django 引导用户

Django:用户登录时发出信号?

用户注册后Django自动登录(1.4)

django forms怎么获取登录用户

Django - 登录后,将用户重定向到他/她所在的页面