是否可以在下次登录时实施“更改密码”在django管理员中输入功能? [英] Is it possible to implement a "change password at next logon" type feature in the django admin?

查看:74
本文介绍了是否可以在下次登录时实施“更改密码”在django管理员中输入功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to be able to set an option in the user's settings that forces them to change their password upon the next login to the admin interface. Is this possible? How would it go about being implemented? I'm using the default auth model right now but not opposed to modifying or changing it. Thanks for any help.

推荐答案

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

I'm actually in the process of doing this myself. You need three components: a user profile (if not already in use on your site), a middleware component, and a pre_save signal.

我的代码是应用程序名为帐户。

My code for this is in an app named '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')

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

First, we create a UserProfile with a foreign key to User. The force_password_change boolean will, as its name describes, be set to true for a user whenever you want to force them to change their password. You could do anything here though. In my organization, we also chose to implement a mandatory change every 90 days, so I also have a DateTimeField that stores the last time a user changed their password. You then set that in the pre_save signal, password_changed_signal.

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

Second, we have the create_user_profile_signal. This is mostly added just for completeness. If you're just now adding user profiles into your project, you'll need a post_save signal that will create a UserProfile every time a User is created. This accomplishes that task.

第三,我们有 password_changed_signal 。这是一个pre_save信号,因为在该过程的这一点上,用户表中的实际行没有被更新。因此,我们可以访问以前的密码和要保存的新密码。如果两者不匹配,那意味着用户已经更改了密码,然后我们可以重新设置force_password_change布尔值。这将是一个要点,也可以照顾您添加的任何其他内容,例如设置之前提到的DateTimeField。

Third, we have the password_changed_signal. This is a pre_save signal because at this point in the process the actual row in the User table hasn't be updated. Therefore, we can access both the previous password and the new password about to be saved. If the two don't match, that means the user has changed their password, and we can then reset the force_password_change boolean. This would be the point, also where you would take care of any other things you've added such as setting the DateTimeField previously mentioned.

最后两行附加两个功能到其适当的信号。

The last two lines attach the two functions to their appropriate signals.

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

If you haven't already, you will also need to add the following line to your project's settings.py (changing the app label and model name to match your setup):

AUTH_PROFILE_MODULE = 'accounts.UserProfile'

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

That covers the basics. Now we need a middleware component to check the status of our force_password_change flag (and any other necessary checks).

# 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/')

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

This very simple middleware hooks into the process_request stage of the page loading process. It checks that 1) the user has already logged in, 2) they are trying to access some page in the admin, and 3) the page they are accessing is not the password change page itself (otherwise, you'd get an infinite loop of redirects). If all of these are true and the force_password_change flag has been set to True, then the user is redirected to the password change page. They will not be able to navigate anywhere else until they change their password (firing the pre_save signal discussed previously).

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

Finally, you just need to add this middleware to your project's settings.py (again, changing the import path as necessary):

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

这篇关于是否可以在下次登录时实施“更改密码”在django管理员中输入功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆