Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用户名在哈希中的Django密码哈希器_Python_Django_Django Authentication_Password Hash - Fatal编程技术网

Python 用户名在哈希中的Django密码哈希器

Python 用户名在哈希中的Django密码哈希器,python,django,django-authentication,password-hash,Python,Django,Django Authentication,Password Hash,也许是一个愚蠢的问题,但如果可能的话,使用username作为salt的一部分来编写BasePasswordHasher子类的最佳方法是什么?我正在从头重写一个站点,并在php中使用了这种方法。问题是在密码哈希器中访问用户名。我真的很高兴能解决这个问题,因为很多用户都会丢失密码,否则的话,请提前向我表示衷心的感谢 PHP代码: function passHash($login, $pass) { return md5(md5($pass).'salt'.$login); } 正如您所注

也许是一个愚蠢的问题,但如果可能的话,使用username作为salt的一部分来编写BasePasswordHasher子类的最佳方法是什么?我正在从头重写一个站点,并在php中使用了这种方法。问题是在密码哈希器中访问用户名。我真的很高兴能解决这个问题,因为很多用户都会丢失密码,否则的话,请提前向我表示衷心的感谢

PHP代码:

function passHash($login, $pass)
{
    return md5(md5($pass).'salt'.$login);
}

正如您所注意到的,这不能仅在密码哈希器中完成。密码哈希器没有关于用户的信息,只有密码和哈希。我想你有两个选择

首先,可能也是最好的,是编写一个自定义。在认证后端级别,我们可以访问用户名和原始密码。看起来是这样的

# settings.py
AUTHENTICATION_BACKENDS=(
    'myapp.backends.LegacyBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# myapp.backends
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.utils.encoding import force_bytes
import hashlib

class LegacyBackend(ModelBackend):

    # We only need to override the authenticate method
    def authenticate(self, username=None, password=None, **kwargs):
        # most of this is copied directly from ModelBackend's authenticate method
        UserModel = get_user_model()
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)

            # This is the normal route that hands off to the password hasher pipeline
            # but we will sidestep it entirely and verify the password here
            #
            # if user.check_password(password):
            #    return user

            pwhash = hashlib.md5(force_bytes(password)).hexdigest()
            hash = hashlib.md5(force_bytes(pwhash+"salt"+username)).hexdigest()
            if hash == user.password:
                # update the user's password if you want, so you can phase out this backend
                user.set_password(password)
                user.save(update_fields=["password"])
                return user

        except UserModel.DoesNotExist:
            UserModel().set_password(password)
请注意,我还没有测试这段代码,但它应该可以像广告中那样工作。此外,您不会与新用户发生冲突,旧用户的密码将更新为新的哈希算法(默认为PBKDF2+SHA256?不确定)


第二个选项是编写一个一次性脚本来修改数据库,使
user.password
字段看起来像
legacymd5$username+salt$hash
。然后,您可以按计划编写自定义密码哈希程序。

正如您所注意到的,这不能仅在密码哈希程序中完成。密码哈希器没有关于用户的信息,只有密码和哈希。我想你有两个选择

首先,可能也是最好的,是编写一个自定义。在认证后端级别,我们可以访问用户名和原始密码。看起来是这样的

# settings.py
AUTHENTICATION_BACKENDS=(
    'myapp.backends.LegacyBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# myapp.backends
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.utils.encoding import force_bytes
import hashlib

class LegacyBackend(ModelBackend):

    # We only need to override the authenticate method
    def authenticate(self, username=None, password=None, **kwargs):
        # most of this is copied directly from ModelBackend's authenticate method
        UserModel = get_user_model()
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)

            # This is the normal route that hands off to the password hasher pipeline
            # but we will sidestep it entirely and verify the password here
            #
            # if user.check_password(password):
            #    return user

            pwhash = hashlib.md5(force_bytes(password)).hexdigest()
            hash = hashlib.md5(force_bytes(pwhash+"salt"+username)).hexdigest()
            if hash == user.password:
                # update the user's password if you want, so you can phase out this backend
                user.set_password(password)
                user.save(update_fields=["password"])
                return user

        except UserModel.DoesNotExist:
            UserModel().set_password(password)
请注意,我还没有测试这段代码,但它应该可以像广告中那样工作。此外,您不会与新用户发生冲突,旧用户的密码将更新为新的哈希算法(默认为PBKDF2+SHA256?不确定)


第二个选项是编写一个一次性脚本来修改数据库,使
user.password
字段看起来像
legacymd5$username+salt$hash
。然后你就可以按计划编写自定义密码哈希程序了。

对于像我一样找到这篇文章的人来说,除了一件事之外,一切都如预期的那样工作。在Django 2.1上,我发现必须在authenticate方法中添加“request”作为第一个参数。他们一定是在某个时候通过了这个。我默默无言地没有通过授权,也不知道为什么。

对于像我一样找到这篇文章的人来说,除了一件事之外,一切都像预期的那样工作。在Django 2.1上,我发现必须在authenticate方法中添加“request”作为第一个参数。他们一定是在某个时候通过了这个。我默默地验证失败,不知道为什么。

你有这个原始算法吗?还有您目前编写的代码吗?编辑原始问题以包含原始代码。还没有开始实施,因为这不是问题所在。我开始阅读,发现输入没有包含用户对象,或者任何我可以利用的东西。我是@Django的新手。Python有一个MD5模块
import MD5
,为了在Django视图中获得一个用户对象,你必须用
user\u object=request.user
(很多有趣的东西随请求一起传递)在你拥有用户对象之后,你可以从中获得很多信息,比如
user\u object.username
user\u object.is\u authenticated()
request.user在登录过程的这一阶段也是可用的吗?嗯。我可以肯定地说这是可能的——我曾经运行过一个Django网站,它通过收购与Rails商店合并,并收购了其他几家初创公司的用户库,这两个公司都有自己的哈希机制——但时间已经够长了,我不记得了任何细节。你有这个原始算法吗?还有您目前编写的代码吗?编辑原始问题以包含原始代码。还没有开始实施,因为这不是问题所在。我开始阅读,发现输入没有包含用户对象,或者任何我可以利用的东西。我是@Django的新手。Python有一个MD5模块
import MD5
,为了在Django视图中获得一个用户对象,你必须用
user\u object=request.user
(很多有趣的东西随请求一起传递)在你拥有用户对象之后,你可以从中获得很多信息,比如
user\u object.username
user\u object.is\u authenticated()
request.user在登录过程的这一阶段也是可用的吗?嗯。我可以肯定地说这是可能的——我曾经运行过一个Django网站,它通过收购与Rails商店合并,并收购了其他几家初创公司的用户库,这两个公司都有自己的哈希机制——但时间已经够长了,我不记得了任何详细信息。尚不知道原因,但在更新try块中的密码后,您必须调用user.save(update_fields=['password'])才能使登录生效。也许你可以修改一下答案。@Kukosk你是对的,这是我的疏忽<代码>用户。设置密码不强制保存。我将编辑应答器。我不知道为什么,但在更新try块中的密码后,您必须调用user.save(update_fields=['password'])才能登录。也许你可以修改一下答案。@Kukosk你是对的,这是我的疏忽<代码>用户。设置密码不强制保存。我将编辑答案