【发布时间】:2018-12-05 18:00:31
【问题描述】:
我查看了与此相关的所有 StackOverflow 问题,但我似乎无法弄清楚这一点。当我对密码进行哈希处理并对其自身进行检查时,它会使用当前代码返回 TypeError "Unicode-objects must be encrypted before hashing":
from scripts import tabledef
from flask import session
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager
import bcrypt
(Unrelated Python code...)
def hash_password(password):
return bcrypt.hashpw(password.encode('utf8'), bcrypt.gensalt())
def credentials_valid(username, password):
with session_scope() as s:
user = s.query(tabledef.User).filter(
tabledef.User.username.in_([username])).first()
if user:
return bcrypt.checkpw(password.encode('utf8'), user.password)
else:
return False
当我尝试通过设置 user.password= user.password.encode('utf8') 来修复此错误时,我得到“无效盐”。
这段代码有什么问题?
更新: 我通过用户的 Flask 输入存储密码:
import json
import sys
import os
import plotly
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from scripts import tabledef
from scripts import forms
from scripts import helpers
from flask import Flask, redirect, url_for, render_template, request, session, flash, Markup
from flask_socketio import SocketIO, emit
@app.route('/', methods=['GET', 'POST'])
def login():
if not session.get('logged_in'):
form = forms.LoginForm(request.form)
if request.method == 'POST':
username = request.form['username'].lower()
password = request.form['password']
if form.validate():
if helpers.credentials_valid(username, password):
session['logged_in'] = True
session['username'] = username
session['email'] = request.form['email']
session['password'] = request.form['password']
return json.dumps({'status': 'Login successful'})
return json.dumps({'status': 'Invalid user/pass'})
return json.dumps({'status': 'Both fields required'})
return render_template('login.html', form=form)
user = helpers.get_user()
return render_template('home.html', user=user)
@app.route('/signup', methods=['GET', 'POST'])
def signup():
if not session.get('logged_in'):
form = forms.LoginForm(request.form)
if request.method == 'POST':
username = request.form['username'].lower()
password = helpers.hash_password(request.form['password'])
email = request.form['email']
if form.validate():
if not helpers.username_taken(username):
helpers.add_user(username, password, email)
session['logged_in'] = True
session['username'] = username
session['email'] = request.form['email']
session['password'] = request.form['password']
return json.dumps({'status': 'Signup successful'})
return json.dumps({'status': 'Username taken'})
return json.dumps({'status': 'User/Pass required'})
return render_template('login.html', form=form)
return redirect(url_for('login'))
这是我得到的错误:
/lib/python3.5/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/env/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/env/lib/python3.5/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/env/lib/python3.5/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/Flaskex-master/app.py", line 34, in login
if helpers.credentials_valid(username, password):
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/Flaskex-master/scripts/helpers.py", line 64, in credentials_valid
return bcrypt.checkpw(password.encode('utf8'), user.password)
File "/home/suraj/Documents/Programming/current-projects/GW_Dining_Tracker/env/lib/python3.5/site-packages/bcrypt/__init__.py", line 101, in checkpw
raise TypeError("Unicode-objects must be encoded before checking")
TypeError: Unicode-objects must be encoded before checking
【问题讨论】:
-
第一个函数应该有一个用于返回的选项卡。打错字了,抱歉。
-
请发布完整的异常,而不仅仅是描述,并提供可运行的示例,以便我们自己重现错误。有关更多信息,请参阅帮助中的minimal reproducible example,但如果您不执行这两个中的至少一个,我们必须猜测哪一行可能会产生该错误。
-
另外,您没有向我们展示您的商店
user.password。但事实上它不是bytes(因为否则你尝试的encode会引发AttributeError)意味着它显然不是从hash_password返回的结果,所以......它是什么? -
您是否有机会将实际密码存储为
user.password,而不是它的bcrypt?如果是这样:你永远不想这样做;使用 bcrypt(或任何密码散列器)的全部意义在于,您不需要将实际用户密码保存在可能泄露的地方。 -
我添加了一些编辑来展示我如何存储密码。我还包括了我收到的错误。但是我将密码作为哈希值存储到数据库中。如果有帮助,密码的数据库类型是简单的 Column(String())。