【发布时间】:2021-01-02 08:07:01
【问题描述】:
我在 models.py 文件中创建了一个用户表,其中包含
models.py
class User(Base):
__tablename__ = "users"
userid = Column(Integer, primary_key=True)
username = Column(String(15), unique=True)
usertype = Column(Boolean)
gender = Column(String(1))
age = Column(Integer)
phone = Column(VARCHAR(15))
password_hash = Column(VARCHAR(128))
@classmethod
def create_password(cls, password):
cls.password_hash = generate_password_hash(password)
return cls.password_hash
@classmethod
def check_password(cls, password):
return check_password_hash(cls.password_hash, password)
def __repr__(self):
return str(self.userid) + ":" + self.username
然后我使用我在 functions.py 文件中编写的 check_password 函数:
functions.py
def search_user(username):
return session.query(models.User).filter_by(username=username).all()
def password_checking(password, username):
usr = search_user(username)[0]
while True:
if usr.check_password(password) == False:
print("Passwords do not match.")
else:
break
我还在数据库中添加了一些用户:
数据库
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
| userid | username | usertype | gender | age | phone | ticket_price | password_hash |
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
| 1 | ashishadmin | 1 | M | 24 | 750792699 | NULL | pbkdf2:sha256:150000$scvDUqJm$8dd6cf55b182391e2558134383d6e91befec40a9e4176a860f3e2158ebaae161 |
| 2 | ashish01 | 0 | M | 24 | 123456789 | NULL | pbkdf2:sha256:150000$ZTSGjGMh$21bb1cab7ea515865645031c993bce532d787f9b2c402246d0387f921ccf0ba8 |
| 3 | ashish02 | 0 | M | 24 | 963852741 | NULL | pbkdf2:sha256:150000$ZDajskIw$f27e76c5d1bcfb2019ffe01d74ddf2381fa61df72cdf830ca689a2aa057ff60c |
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
现在,当我尝试使用以下方法测试检查密码功能时:
print(password_checking("testing123", "ashish01"))
它给了我以下错误:
Traceback (most recent call last):
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\sql\elements.py", line 747, in __getattr__
return getattr(self.comparator, key)
AttributeError: 'Comparator' object has no attribute 'count'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\myenv\ticket_booking\functions.py", line 95, in <module>
print(password_checking("testing123", "ashish01"))
File "c:\myenv\ticket_booking\functions.py", line 83, in password_checking
if usr.check_password(password) == False:
File "c:\myenv\ticket_booking\models.py", line 47, in check_password
return check_password_hash(cls.password_hash, password)
File "c:\myenv\ticket_booking\lib\site-packages\werkzeug\security.py", line 218, in check_password_hash
if pwhash.count("$") < 2:
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\orm\attributes.py", line 238, in __getattr__
util.raise_(
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\util\compat.py", line 182, in raise_
raise exception
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.password_hash has an attribute 'count'
我也曾尝试在 function.py 文件中定义的 add_user 函数中使用该函数,以检查重新输入的密码是否运行良好,但我不明白为什么这种方式不起作用并给了我一个错误。
functions.py
password = getpass("Enter password: ")
pass_len = len(password)
while pass_len < 8:
print("Password length should be greater or equal to 8, please enter again.")
password = getpass("Enter password: ")
pass_len = len(password)
password_hash = models.User.create_password(password)
while True:
re_password = getpass("Re-enter password: ")
if models.User.check_password(re_password) == False:
print("Passwords do not match.")
else:
break
注意:我正在使用 werkzeug.security 来创建密码哈希。
【问题讨论】:
-
This GitHub issue 是我通过在线查找得到的最佳匹配。我自己不能轻易测试它,但您的
password_hash可能实际上不是Column对象,不知何故。但是,您的代码对我来说似乎很好,除了password_hash在User模型中的奇怪重新定义(它首先无缘无故地设置为None) -
为什么
check_password是一个类方法?您希望它是一个实例方法,因此它检查用户的password属性的值,而不是类的值,它是一个列。 -
@snakecharmerb 我最初是这样做的,但那会产生 TypeError。
-
@OctaveL 我尝试使用
session.execute(select([models.User.password_hash]))来检查password_hash 是否是一个列对象,并且运行良好。在对象上运行一个循环给了我所有的哈希键行。
标签: python sqlalchemy