简体   繁体   中英

Changing user's password using Flask and SQLite

I am trying to implement a function to change the user's password. I am storing only the hash in DB not the password and I want to ask the user to enter the old password first then the new one. I want to check if the old password's hash is matching the one stored in DB and if so, to update it with the new one. I am doing something wrong as the code is not passing the validation checks and I am having an error: "Invalid password". Any help, would be appreciated.

@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")

There are quite some problems with your code...

The biggest problem

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

You have to search for the user name, not for the hash,,, Imagine. two users have the same password. or a user enters the wrong password. but that is the password of another user...

I never used direct access to sqlite, only via sqlalchemy, but from a quick look at the docs ( https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.executemany ) db.execute does not return eg rows, but you need to query it.

eg after your db.execute you need to do a db.fetchone or db.fetchall , see above linked documentation.

Also, the order of your code could be improved.

eg first, you generate the hash of a new password, and then afterwards you check whether there is a password at all - this should be switched.

Speaking of validation, much of it could be done via eg flask-wtforms, so you don't need so much validation code on your own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM