为什么 check_password_hash 函数返回 false?使用 Flask、SQLite3 和 Werkzeug
Why is check_password_hash function returning false? Using Flask, SQLite3 and Werkzeug
我正在尝试使用 Flask、Werkzeug 和 SQLite 创建一个基本的登录功能。
用户可以注册并且他们的密码哈希存储在 SQLite 数据库中,但是当我尝试使用正确的密码登录时 check_password_hash returns false.
目前我正在将用户提供的密码与存储在 SQLite 数据库中的相关哈希进行比较,该数据库是在用户注册时使用 generate_password_hash 创建的。
我已阅读 Werkzeug 文档,但找不到任何解决方案。
也许这与 generate_password_hash 从不输出相同的散列两次有关?尽管我认为 check_password_hash 能够解决这个问题?
代码如下:
@app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""
if request.method == "GET":
return render_template("register.html")
if request.method == "POST":
with sqlite3.connect("finance.db") as conn:
cur = conn.cursor()
username = request.form.get("username")
password = request.form.get("password")
confirm_password = request.form.get("confirm-password")
hash_value = generate_password_hash(password)
cur.execute("SELECT * FROM users WHERE username=?", (username,))
valid_username = cur.fetchone()
# Check input and format: Username already taken? Username entered? Password entered? passwords match?
if valid_username:
return ("Username not available")
if not username:
return("Please enter a username")
elif not password:
return("Please enter a password")
elif not confirm_password:
return("Please confirm your password")
elif password != confirm_password:
return ("Passwords do not match")
else:
cur.execute("INSERT INTO users (username,hash) VALUES (?,?)", (username,hash_value))
return redirect("/")
@app.route("/login", methods=["GET", "POST"])
def login():
"""Log user in"""
# Forget any user_id
session.clear()
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure username was submitted
if not request.form.get("username"):
return apology("must provide username", 403)
# Ensure password was submitted
elif not request.form.get("password"):
return apology("must provide password", 403)
# User login
# Query database for username and hash
with sqlite3.connect("finance.db") as conn:
cur = conn.cursor()
username_field = request.form.get("username")
cur.execute("SELECT username FROM users WHERE username = ?", (username_field,))
username = cur.fetchall()
cur.execute("SELECT hash FROM users WHERE username = ?", (username_field,))
pwhash = cur.fetchone()
# Ensure username exists and password is correct
if len(username) != 1 or not check_password_hash(pwhash, request.form.get("password")):
print(check_password_hash(pwhash, request.form.get("password")))
return apology("invalid username and/or password", 403)
return redirect("/")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("login.html")
在此先感谢您的帮助。
啊哈!解决了。语法错误,pwhash` 是一个元组,因为那是 fetchone() returns,所以它需要是 check_password_hash(pwhash[0], request.form.get("password")) 谢谢这么多的支持。我没有想到要单独测试 check_password_hash 函数,这样做让我意识到我正在使用一个元组。干杯@JanL。祝你有个愉快的一天。
我正在尝试使用 Flask、Werkzeug 和 SQLite 创建一个基本的登录功能。 用户可以注册并且他们的密码哈希存储在 SQLite 数据库中,但是当我尝试使用正确的密码登录时 check_password_hash returns false.
目前我正在将用户提供的密码与存储在 SQLite 数据库中的相关哈希进行比较,该数据库是在用户注册时使用 generate_password_hash 创建的。 我已阅读 Werkzeug 文档,但找不到任何解决方案。
也许这与 generate_password_hash 从不输出相同的散列两次有关?尽管我认为 check_password_hash 能够解决这个问题?
代码如下:
@app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""
if request.method == "GET":
return render_template("register.html")
if request.method == "POST":
with sqlite3.connect("finance.db") as conn:
cur = conn.cursor()
username = request.form.get("username")
password = request.form.get("password")
confirm_password = request.form.get("confirm-password")
hash_value = generate_password_hash(password)
cur.execute("SELECT * FROM users WHERE username=?", (username,))
valid_username = cur.fetchone()
# Check input and format: Username already taken? Username entered? Password entered? passwords match?
if valid_username:
return ("Username not available")
if not username:
return("Please enter a username")
elif not password:
return("Please enter a password")
elif not confirm_password:
return("Please confirm your password")
elif password != confirm_password:
return ("Passwords do not match")
else:
cur.execute("INSERT INTO users (username,hash) VALUES (?,?)", (username,hash_value))
return redirect("/")
@app.route("/login", methods=["GET", "POST"])
def login():
"""Log user in"""
# Forget any user_id
session.clear()
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure username was submitted
if not request.form.get("username"):
return apology("must provide username", 403)
# Ensure password was submitted
elif not request.form.get("password"):
return apology("must provide password", 403)
# User login
# Query database for username and hash
with sqlite3.connect("finance.db") as conn:
cur = conn.cursor()
username_field = request.form.get("username")
cur.execute("SELECT username FROM users WHERE username = ?", (username_field,))
username = cur.fetchall()
cur.execute("SELECT hash FROM users WHERE username = ?", (username_field,))
pwhash = cur.fetchone()
# Ensure username exists and password is correct
if len(username) != 1 or not check_password_hash(pwhash, request.form.get("password")):
print(check_password_hash(pwhash, request.form.get("password")))
return apology("invalid username and/or password", 403)
return redirect("/")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("login.html")
在此先感谢您的帮助。
啊哈!解决了。语法错误,pwhash` 是一个元组,因为那是 fetchone() returns,所以它需要是 check_password_hash(pwhash[0], request.form.get("password")) 谢谢这么多的支持。我没有想到要单独测试 check_password_hash 函数,这样做让我意识到我正在使用一个元组。干杯@JanL。祝你有个愉快的一天。