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

时间:2017-12-05 12:12:50

标签: flask bcrypt password-encryption

我知道有一个类似的问题被问到here,但似乎没有答案可以解决我的问题。我使用的是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)

1 个答案:

答案 0 :(得分:0)

所以我想出来了,答案真的与这个问题无关。

问题是,在注册时,我使用new_user实例化了对象password=hashed_password,但随后我调用了form.populate_obj(new_user),根据wtforms docs,这是一个破坏性操作,结果覆盖了new_user.password = form.password.data,但没有进行哈希处理。

所以我将未散列的密码存储在我的数据库中,并且在登录时,我将散列的候选密码与未散列的存储密码进行比较。因此,无效的盐。正如在其他相关事项中所讨论的那样,无效盐错误是一个巨大的陷阱,并没有真正指出潜在的问题。

要修复,我先调用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