无法在Flask中验证散列密码

时间:2014-11-23 17:56:19

标签: mongodb flask passwords

我正在为烧瓶应用构建用户名/密码验证。当用户注册时,我将用户名和密码存储在mongodb文档中。

这是我的用户模型:

class User():

def __init__(self, userid=None,username=None,password=None):
    self.userid= userid
    self.username = username
    self.password = generate_password_hash(password)

def __repr__(self):
    return '<User %r>' % self.username

def is_authenticated(self):
    return True

def is_active(self):
    return True

def is_anonymous(self):
    return False

def get_id(self):
    try:
        return unicode(self.userid) 
    except NameError:
        return unicode(self.userid)  

我使用werkzeug库方法generate_password_hash和check_password_hash分别生成/检查密码。

这是我将用户数据转储到mongodb的代码:

def db_dump(data):
            k = {'username':data.username,'password':data.password}
            db.users.insert(k,True)

这是我用于通过用户名检索用户数据的代码:

def find_by_username(username):
        data = self.db.users.find_one({'username': username})
        user = User(userid=unicode(data['_id']),username=data['username'],password=data['password'])
        return user

这是我的问题。让我们说我有一个用户&#39; jon&#39;有密码&#39; abcd&#39;。当我运行代码以通过控制台检查新用户的密码哈希时,它可以正常工作:

>> check_password_hash(generate_password_hash('abcd'),'abcd')
True

然而,在&#39; jon&#39;已注册并且他的信息已被转储到数据库中,在随后的登录尝试中,我必须从数据库中检索哈希密码,检查不起作用:

>>check_password_hash(find_by_username('jon').password,'abcd')
False

知道为什么会这样吗?经过一些谷歌搜索我的第一直觉是,我可能需要以不同的方式在mongodb中存储或检索哈希密码,因为它似乎被存储为字符串。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我认为问题在于,当您在User方法中实例化find_by_username对象时,您将对密码进行双重哈希处理。该方法从DB中获取包含散列密码的信息。然后,它会使用该数据创建一个User对象。 User对象在generate_password_hash方法中调用__init__。因此,密码被双重哈希,因此check_password_hash检查失败。

您可以考虑将密码哈希移动到将User对象保存到数据库时调用的函数。您想要检测密码是否已更改,因此您不会反复重新密码。可能还有其他方法可以解决这个问题,但简而言之,您可能希望将密码哈希移出__init__调用。