-1

我正在使用 passlib 将密码存储在我的 sqlite 数据库中。存储新密码(注册)时我没有收到错误。但是,当我尝试使用同一用户登录时,我收到此错误“TypeError:哈希必须是 unicode 或字节,而不是 sqlalchemy.orm.attributes.InstrumentedAttribute”。

我的剧本

**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

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

4

1 回答 1

3

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

password_check = check_encrypted_password(password1,Login.password)

应该

password_check = check_encrypted_password(password1,hashed)

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

您应该注意代码中的许多其他错误。

  1. 大多数时候您使用“password1”,但也有一个“password”实例。
  2. 如果提供的用户名不在数据库中,则不会定义“logged_email_id”和“hashed”变量。

因此,我建议将您的代码重构为:

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. 将“password1”替换为“password”,以确保“user.password=password”不会因为未定义密码而产生错误。
  2. 将 for 循环替换为“one_or_none()”。如果找不到用户名,则返回第一个值或无。
  3. 在尝试使用查询结果之前,请检查从数据库查询返回的值是否存在。
于 2020-08-28T15:57:43.687 回答