#python #flask #werkzeug
#python #flask #werkzeug
Вопрос:
Я пытаюсь создать базовую функцию входа в систему, используя Flask, Werkzeug и SQLite. Пользователи могут регистрироваться, а хэш их пароля хранится в базе данных SQLite, хотя, когда я пытаюсь войти в систему, используя правильный пароль, check_password_hash возвращает 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")
Заранее спасибо за любую помощь.
Комментарии:
1. Пожалуйста, добавьте код, который вы использовали для генерации хэша.
2. Просто добавил его. Дайте мне знать, если вам нужно увидеть больше.
3. Хорошо, спасибо. Я не вижу ничего явно неправильного. Итак… Я предполагаю
print(check_password_hash(pwhash, request.form.get("password")))
, что печатаетFalse
? Можете ли вы также распечатать значенияpwhash
иrequest.form.get("password")
?4.Вот и все:
print(check_password_hash(pwhash, request.form.get("password")))
печатаетFalse
print(pwhash)
печатает('pbkdf2:sha256:150000$AjKdB2Df$838cba14de17eb43bcd7f93dc1eea89fdbeb59c10d422a8bc50e32a04b959018',)
иprint(request.form.get("password"))
печатаетonaj
, это правильный пароль, который я ввел.5. Я не уверен, почему он печатает false, потому что: ` >>> из werkzeug.security импортируйте check_password_hash >>> check_password_hash(«pbkdf2:sha256:150000$AjKdB2Df$838cba14de17eb43bcd7f93dc1eea89fdbeb59c10d422a8bc50e32a04b959018» , «onaj») Верно >>> `
Ответ №1:
Ага! Решил это. Синтаксическая ошибка, pwhash` — это кортеж, потому что это то, что возвращает fetchone(), поэтому он должен быть check_password_hash(pwhash[0], request.form.get(«пароль»)) Большое спасибо за поддержку. Мне не приходило в голову тестировать функцию check_password_hash изолированно, это заставило меня понять, что я работаю с кортежем. Приветствия @JanL. Хорошего дня.