2017-10-12 42 views
0

我有一個Users表與password列這樣定義:密碼比較返回錯誤

password | text | not null

而且一SQLAlchemy的模型這樣定義:

password = db.Column(PasswordType(schemes=['bcrypt'], max_length=128), nullable=False)

我可以成功地插入一行使用此型號:

user = Users(first_name='James', last_name='Bond', password='aaa') 
db.session.add(user) 
db.session.commit() 

但選擇行回來的時候我不能比較的密碼:

user = db.session.query(Users).join(ContactDetails).\ 
      filter(ContactDetails.email == '[email protected]').first() 
assert user.password == 'aaa' 

這將導致以下錯誤:

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../../.virtualenvs/amazon_sales/lib/python2.7/site-packages/sqlalchemy_utils/types/password.py:60: in __eq__ 
    valid, new = self.context.verify_and_update(value, self.hash) 
../../../../.virtualenvs/amazon_sales/lib/python2.7/site-packages/passlib/context.py:2417: in verify_and_update 
    record = self._get_or_identify_record(hash, scheme, category) 
../../../../.virtualenvs/amazon_sales/lib/python2.7/site-packages/passlib/context.py:2026: in _get_or_identify_record 
    return self._identify_record(hash, category) 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <passlib.context._CryptConfig object at 0x10f5e7090>, hash = '\\x2432622431322457475a794c4e4a5973704e4f7750444b322e3766302e336c58365778506e7050767a2e6f394d317748716650717174796a6e4d3475' 
category = None, required = True 

    def identify_record(self, hash, category, required=True): 
     """internal helper to identify appropriate custom handler for hash""" 
     # NOTE: this is part of the critical path shared by 
     #  all of CryptContext's PasswordHash methods, 
     #  hence all the caching and error checking. 
     # FIXME: if multiple hashes could match (e.g. lmhash vs nthash) 
     #  this will only return first match. might want to do something 
     #  about this in future, but for now only hashes with 
     #  unique identifiers will work properly in a CryptContext. 
     # XXX: if all handlers have a unique prefix (e.g. all are MCF/LDAP), 
     #  could use dict-lookup to speed up this search. 
     if not isinstance(hash, unicode_or_bytes_types): 
      raise ExpectedStringError(hash, "hash") 
     # type check of category - handled by _get_record_list() 
     for record in self._get_record_list(category): 
      if record.identify(hash): 
       return record 
     if not required: 
      return None 
     elif not self.schemes: 
      raise KeyError("no crypt algorithms supported") 
     else: 
>   raise ValueError("hash could not be identified") 
E   ValueError: hash could not be identified 

../../../../.virtualenvs/amazon_sales/lib/python2.7/site-packages/passlib/context.py:1131: ValueError 
+0

您是否能夠以與輸入相同的方式檢索密碼,或者在提交時是否在密碼中附加了額外的字符,導致比較時不匹配? – Mohammed

回答

0

使用bcrypt的一點是商店數據庫中的明文密碼。取而代之的是存儲密碼的哈希值(如果這不明確,你應該閱讀PasswordTypeOWASP Authentication Cheat Sheet的文檔,並確保你明白它。)

你正在做的是存儲一個bcrypt'通過SQLAlchemy的魔術編密碼,並比較該明文密碼:

assert user.password == 'aaa' 

,而你應該bcrypt'ing密碼,結果什麼是存儲在數據庫中進行比較。看看bcrypt.hashpw

+0

仔細查看我在模型中使用的密碼類型;) – ruipacheco

+0

'PasswordType(schemes = ['bcrypt'] ...''? – a2800276

+0

確切地說,這改變了一切。 – ruipacheco