我正在为烧瓶应用构建用户名/密码验证。当用户注册时,我将用户名和密码存储在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中存储或检索哈希密码,因为它似乎被存储为字符串。有什么想法吗?
答案 0 :(得分:0)
我认为问题在于,当您在User
方法中实例化find_by_username
对象时,您将对密码进行双重哈希处理。该方法从DB中获取包含散列密码的信息。然后,它会使用该数据创建一个User
对象。 User
对象在generate_password_hash
方法中调用__init__
。因此,密码被双重哈希,因此check_password_hash
检查失败。
您可以考虑将密码哈希移动到将User
对象保存到数据库时调用的函数。您想要检测密码是否已更改,因此您不会反复重新密码。可能还有其他方法可以解决这个问题,但简而言之,您可能希望将密码哈希移出__init__
调用。