flask-bcrypt 无效盐;编码问题?

flask-bcrypt Invalid Salt; encoding issue?

我知道有人问过类似的问题 ,但似乎没有答案能解决我的问题。我正在使用 Python3、Flask 和 flask-bcrypt。

我的登录功能早些时候运行良好,我认为我没有更改任何内容,所以我不确定发生了什么。我的理解是,在注册时,我们打算将收到的密码编码为 UTF-8,然后在将哈希密码传递给数据库之前对其进行解码,如下所示:

password = form.password.data.encode('utf-8')
hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')

然后,在登录时,我们应该对候选密码进行编码,并将其与数据库中的散列密码进行比较,如下所示:

password = form.password.data.encode('utf-8')
if bcrypt.check_password_hash(user.password, password):

但是我从中得到了无效盐的错误。而且我尝试了其他几种变体但没有成功。

如有任何帮助,我们将不胜感激。以下是观点。我可以提供任何其他必要的代码。

@app.route('/<role>/signup/', methods=['GET', 'POST'])
def signUp(role):
    form = RegisterForm()

    if form.validate_on_submit():
        password = form.password.data.encode('utf-8')
        hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
        new_user = User(role=role, password=hashed_password, visits=1)
        form.populate_obj(new_user)

        db.session.add(new_user)
        db.session.commit()

        login_user(new_user)

        return redirect(url_for('createContactInfo', user_id=current_user.id))

    return render_template('signup.html', form=form, role=role)

@app.route('/login/', methods=['GET', 'POST'])
def logIn():
    form = LoginForm()

    if form.validate_on_submit():
        password = form.password.data.encode('utf-8')
        user = User.query.filter_by(email=form.email.data).first()
        if user:
            if bcrypt.check_password_hash(user.password, password):
                login_user(user, remember=form.remember.data)
                User.query.filter_by(id=current_user.id).update({'visits': User.visits + 1})
                db.session.commit()

                if current_user.role == 'admin':
                    return redirect(url_for('adminMainPage', user_id=current_user.id))
                elif current_user.role == 'guest':
                    return redirect(url_for('guestMainPage', user_id=current_user.id))
                else:
                    return "wrong role!"

            flash('Invalid login')
            return render_template('login.html', form=form)

        flash('Invalid login')
        return render_template('login.html', form=form)

    return render_template('login.html', form=form)

所以我想通了,答案真的和问题无关。

问题是,在注册时,我用 password=hashed_password 实例化了对象 new_user,但后来我调用了 form.populate_obj(new_user),根据 wtforms docs 这是一个破坏性的操作,结果覆盖了未散列的 new_user.password = form.password.data

所以我将未经哈希处理的密码存储在我的数据库中,并且在登录时,我将经过哈希处理的候选密码与未经哈希处理的存储密码进行比较。因此,无效的盐。正如在其他相关问题中所讨论的,Invalid Salt 错误是一个巨大的包罗万象的东西,并没有真正指出根本问题。

为了修复,我先调用了form.populate_obj(new_user),然后分别添加属性如下:

    new_user = User()

    form.populate_obj(new_user)

    new_user.role = role
    new_user.password = hashed_password
    new_user.visits = 1