2014-11-23 30 views
0

我正在构建烧瓶应用程序的用户名/密码验证。当用户注册时,我将用户名和密码存储在一个mongodb文档中。无法在Flask中验证散列密码

这是我的用户模型:

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 

这里是我的问题。假设我有一个用户'jon',其密码为'abcd'。当我运行的代码来检查密码哈希为新用户直通控制台,它工作正常:

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

然而,经过“乔恩已经签署了与他的信息已经被倾倒到数据库中,在随后尝试登录时,我不得不从数据库中检索哈希密码,检查不工作:

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

任何想法,为什么发生这种情况?一些谷歌搜索后,我的第一本能是,也许我需要以不同的方式在mongodb中存储或检索哈希密码,因为它似乎被存储为一个字符串。有任何想法吗?

+0

你解决了这个问题吗? – aezell 2015-01-16 18:18:02

回答

0

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

您可能会考虑将密码散列值移动到一个函数,该函数在将User对象保存到数据库时调用。你会想要检测密码是否已经改变,所以你没有反复刷新密码。还有其他方法可以处理这个问题,但总之,您可能需要将密码散列在__init__之外。