我知道有一个类似的问题被问到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)
答案 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