使用 passlib 可以注册密码,但无法再次验证它出现错误



我正在使用passlib将密码存储在sqlite数据库中。我在存储新密码(注册(时没有出错。但是,当我尝试使用同一用户登录时,我会收到以下错误"TypeError:hash必须是unicode或字节,而不是sqlalchemy.orm.attributes.EInstrumentedAttribute".

我的脚本

**models.py**
class Login(db.Model,UserMixin):
"Creates username and password"
id = db.Column(db.Integer,primary_key=True,nullable=False)
username = db.Column(db.String,nullable=False)
password = db.Column(db.String,nullable=False)
email = db.Column(db.String,nullable=False)
def __repr__(self):
return f"Login('{self.id}','{self.username}','{self.password}','{self.email}')"
**routes.py**
from myfolder.security import encrypt_password,check_encrypted_password
def login():

if request.method == 'POST':
username = request.form.get('username')
password1 = request.form.get('password')
data = {'username':username}
#fetch the email id of the user whose logged in
user_email_id = Login.query.filter(Login.username==username).values(Login.email,Login.password)
for logged_user in user_email_id:
logged_email_id = logged_user.email
hashed = logged_user.password
session['logged_user'] = logged_email_id
completion = validate(username)
if completion ==False:
error = 'error.'
else:
password_check = check_encrypted_password(password1,Login.password)
if password_check ==False:
error = 'error.'
else:
user = Login()
user.name=username
user.password=password
login_user(user)
error = 'Success'
api_response = {'data':data,'error':error}
return jsonify(api_response)

我创建了一个名为security.py 的新文件

from passlib.context import CryptContext
pwd_context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
pbkdf2_sha256__default_rounds=30000
)

def encrypt_password(password):
return pwd_context.encrypt(password)

def check_encrypted_password(password, hashed):
return pwd_context.verify(password, hashed)

在登录方法中,我尝试了不同的方法,但都不起作用。我试着在这里传递密码。password_check = check_encrypted_password(password1,password)但是我收到这个错误

raise ValueError("hash could not be identified")
ValueError: hash could not be identified

我应该如何验证我的密码和登录?

您的代码中有一个错误。线路

password_check = check_encrypted_password(password1,Login.password)

应该是

password_check = check_encrypted_password(password1,hashed)

您当前不是从数据库中传入散列密码,而是传入密码的sqlalchemy列定义。

您的代码中还有许多其他错误需要注意。

  1. 大多数时候你使用";密码1";,但是也存在一个";密码">
  2. 如果提供了不在数据库中的用户名;logged_email_id";以及";散列的";变量将不会被定义

所以我建议将代码重构为:

from myfolder.security import encrypt_password,check_encrypted_password
def login():    
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
data = {'username':username}
#fetch the email id of the user whose logged in
logged_user = Login.query.filter(Login.username==username).values(Login.email,Login.password).one_or_none()
if not logged_user:
error = 'error.'
else:
session['logged_user'] = logged_user.email
completion = validate(username)
if completion ==False:
error = 'error.'
else:
password_check = check_encrypted_password(password,logged_user.password)
if password_check ==False:
error = 'error.'
else:
user = Login()
user.name=username
user.password=password
login_user(user)
error = 'Success'
api_response = {'data':data,'error':error}
return jsonify(api_response)

在这个代码中,我有:

  1. 替换";密码1";用";密码";,以确保";user.password=密码";未生成错误,因为未定义密码
  2. 将for循环替换为";one_or_none(("。如果找不到用户名,则返回第一个值或none
  3. 在尝试使用查询结果之前,请检查数据库查询返回的值是否存在

最新更新