Я пытаюсь реализовать функцию изменения пароля пользователя. Я храню в БД только хэш, а не пароль, и я хочу попросить пользователя сначала ввести старый пароль, а затем новый. Я хочу проверить, совпадает ли хеш старого пароля с хешем, хранящимся в БД, и, если да, обновить его новым. Я делаю что-то не так, так как код не проходит проверки, и у меня появляется ошибка: «Неверный пароль». Любая помощь будет оценена.

@app.route("/change_password", methods=["GET", "POST"])
@login_required
def change_password():

    user_id=session["user_id"]

    if request.method=="POST":

        password = request.form.get("password")
        hash = generate_password_hash(password)
        new_password = request.form.get("new_password")
        confirm_new_password = request.form.get("confirm_new_password")
        new_hash = generate_password_hash(new_password)
        #Validations:
        if not password:
            return apology("must provide password", 400)


        if not new_password:
            return apology("must provide a new password", 400)


        #Ensure password confirmation is provided
        if not confirm_new_password:
            return apology("must confirm new password", 400)
        #Check if new password matches
        if new_password!= confirm_new_password:
            return apology("password does not match", 400)
        # Query database for the current password
        rows = db.execute("SELECT * FROM users WHERE hash = ?", hash)

        # Ensure username exists and password is correct
        if len(rows) != 1:
            return apology("invalid password", 400)
        #Update DB with the new_hash
        else:
            db.execute ("UPDATE users SET hash=:new_hash WHERE id=:id", new_hash = new_hash, id = user_id)
        return redirect("/")

    else:
        return render_template("change_password.html")
0
Plain Jane 29 Мар 2021 в 23:21

1 ответ

Лучший ответ

С вашим кодом довольно много проблем ...

Самая большая проблема

rows = db.execute("SELECT * FROM users WHERE hash = ?", hash)

Искать нужно по имени пользователя, а не по хешу !!! Представьте, что у двух пользователей одинаковый пароль, или пользователь вводит неправильный пароль, но это пароль другого пользователя ...

Я никогда не использовал прямой доступ к sqlite, только через sqlalchemy, но беглый просмотр документации (https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.executemany) db.execute не возвращает, например строк, но вам нужно запросить его.

Например после db.execute вам нужно сделать db.fetchone или db.fetchall, см. документацию по ссылке выше.

Кроме того, порядок вашего кода может быть улучшен.

Например сначала вы генерируете хеш нового пароля, а потом проверяете, есть ли вообще пароль - его нужно поменять.

Говоря о валидации, многое из этого можно было бы сделать, например, с помощью flask-wtforms, поэтому вам не нужно столько кода проверки самостоятельно.

0
J.G. 29 Мар 2021 в 21:05