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
我知道有人问过类似的问题
我的登录功能早些时候运行良好,我认为我没有更改任何内容,所以我不确定发生了什么。我的理解是,在注册时,我们打算将收到的密码编码为 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