python - 是否可以在 django admin 中实现 "change password at next logon"类型的功能?

标签 python django

我希望能够在用户设置中设置一个选项,强制他们在下次登录管理界面时更改密码。这可能吗?它将如何实现?我现在正在使用默认的身份验证模型,但不反对修改或更改它。感谢您的帮助。

最佳答案

我自己实际上正在这样做。您需要三个组件:用户配置文件(如果您的站点上尚未使用)、中间件组件和 pre_save 信号。

我的代码在一个名为“accounts”的应用中。

# myproject/accounts/models.py

from django.db import models
from django.db.models import signals
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    force_password_change = models.BooleanField(default=False)

def create_user_profile_signal(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

def password_change_signal(sender, instance, **kwargs):
    try:
        user = User.objects.get(username=instance.username)
        if not user.password == instance.password:
          profile = user.get_profile()
          profile.force_password_change = False
          profile.save()
    except User.DoesNotExist:
        pass

signals.pre_save.connect(password_change_signal, sender=User, dispatch_uid='accounts.models')

signals.post_save.connect(create_user_profile_signal, sender=User, dispatch_uid='accounts.models')

首先,我们创建一个带有 User 外键的 UserProfile。 force_password_change bool 值,正如其名称所描述的,在您想要强制用户更改密码时为用户设置为 true。你可以在这里做任何事情。在我的组织中,我们还选择每 90 天实现一次强制更改,因此我还有一个 DateTimeField 来存储用户上次更改密码的时间。然后在 pre_save 信号 password_changed_signal 中设置它。

其次,我们有 create_user_profile_signal。这主要是为了完整性而添加的。如果您现在刚刚将用户配置文件添加到您的项目中,您将需要一个 post_save 信号,该信号将在每次创建用户时创建一个 UserProfile。这样就完成了这项任务。

第三,我们有 password_changed_signal。这是一个 pre_save 信号,因为在此过程中,用户表中的实际行尚未更新。因此,我们既可以访问以前的密码,也可以访问即将保存的新密码。如果两者不匹配,则意味着用户更改了密码,然后我们可以重置 force_password_change bool 值。这就是重点,您还需要处理您添加的任何其他内容,例如设置前面提到的 DateTimeField。

最后两行将这两个函数附加到它们相应的信号上。

如果您还没有,您还需要将以下行添加到项目的 settings.py(更改应用标签和模型名称以匹配您的设置):

AUTH_PROFILE_MODULE = 'accounts.UserProfile'

这涵盖了基础知识。现在我们需要一个中间件组件来检查 force_password_change 标志的状态(以及任何其他必要的检查)。

# myproject/accounts/middleware.py

from django.http import HttpResponseRedirect

import re

class PasswordChangeMiddleware:
    def process_request(self, request):
        if request.user.is_authenticated() and \
            re.match(r'^/admin/?', request.path) and \
            not re.match(r'^/admin/password_change/?', request.path):

            profile = request.user.get_profile()
            if profile.force_password_change:
                return HttpResponseRedirect('/admin/password_change/')

这个非常简单的中间件 Hook 到页面加载过程的 process_request 阶段。它会检查 1) 用户已经登录,2) 他们正在尝试访问管理员中的某个页面,以及 3) 他们正在访问的页面不是密码更改页面本身(否则,你会得到一个无限循环重定向)。如果所有这些都为真并且 force_password_change 标志已设置为 True,则用户将被重定向到密码更改页面。在更改密码(触发前面讨论的 pre_save 信号)之前,他们将无法导航到其他任何地方。

最后,您只需将此中间件添加到项目的 settings.py 中(同样,根据需要更改导入路径):

MIDDLEWARE_CLASSES = (
    # Other middleware here
    'myproject.accounts.middleware.PasswordChangeMiddleware',
)

关于python - 是否可以在 django admin 中实现 "change password at next logon"类型的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2093593/

相关文章:

django/商业/ Paypal : keeping track of user transactions

python - 如何在 Django 中的大型描述上设置 "see more"选项?

python - Python 中的循环切片

Python raw_input 不会提示

Python:Pandas Groupby 然后失败率

python - 我可以将 apache mahout 与 django 应用程序一起使用吗

python - 在 Django 中将 CSS 添加到 Pdfkit?

python - 使用两个版本的 Python (Windows) 安装 IPython

python - 问题获取最大子数组的开始

python - 今天发生的 Django 过滤器事件