Сравнение пароля возвращает ошибку

У меня есть 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 == 'james.bond@gmail.com').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

1 ответ

Смысл использования bcrypt состоит в том, чтобы не хранить незашифрованный пароль в базе данных. Вместо этого сохраняется хеш пароля (если вам это не понятно, вам следует прочитать документацию PasswordType и бланк проверки подлинности OWASP и убедитесь, что вы понимаете это.)

Что вы делаете, это сохраняете пароль bcrypt с помощью магии SQLAlchemy и сравниваете его с открытым текстом:

assert user.password == 'aaa'

в то время как вы должны зашифровать пароль и сравнить результат с тем, что хранится в базе данных. Посмотри на bcrypt.hashpw,

Другие вопросы по тегам