简体   繁体   中英

In Python/SQLite3, How does one define a variable to be used to query a database table?

I have a table with three columns

  id  username  password
  ----------------------
  1  Jdoe      $2a$12$sv97wrhscHkKVMZ8P/2yw.O/cz8pWUE/1zlTyFNJ9.jCYhR8Nw9Iu
  2  user      $2a$12$dLeSlYFyPdP1WhA4Tw21ZuX5v5XH55.yK2XApMd4VglUDRJEd4Lmy

My aim is to authenticate user based on the password provided at login. To achieve this I have written Python code that looks like this:

from bcrypt import hashpw, gensalt


if request.method == 'POST':
      if form.validate() == False:

         return render_template('login.html', form = form)
      else:
         #return render_template('index.html')
         password = request.form['password']
         password = hashpw(password, gensalt())
         con = sql.connect("testDB.db")
         cur = con.cursor()
         cur.execute("SELECT * FROM mytable where password =?", (password,))

         if cur.fetchall():
              return "welcome guest"
         else:
              return "user not found"

However when I enter an existing password the system returns the message "user not found". The desired output is for the message "Welcome guest".The hashpw and gensalt() are imported from bcrypt .

I am pretty sure I am defining the variable "password" wrongly. How does one properly define such a variable?

You are generating a new hash , one with a totally different salt:

password = hashpw(password, gensalt())

You can't look up users by password; the whole point of using a salted hash is to make the impossible for hackers to use a rainbow table (common passwords hashed, but without a salt) to match hashes. That same protection makes it impossible for you to know, up-front, what salt was used for a given user, and you are almost guaranteed to be generating a different hash from your new salt.

You need to use the username to look up the right now, retrieve the salted password, then ask the bcrypt.checkpw() function to securely test the password against the stored hash. The hash value includes the salt, bcrypt will extract the salt and use it to verify that the same hash is generated. The comparison needs to protect against timing attacks, don't re-implement this check yourself.

Your form needs to send along the username, not just the password:

from bcrypt import checkpw


username = request.form['username']
password = request.form['password']
con = sql.connect("testDB.db")
cur = con.cursor()
cur.execute("SELECT password FROM mytable where username = ?", (username,))
hashed = cur.fetchone()
if hashed is None or not checkpw(password, hashed[0]):
    # no such user, *or* the password did not match
    return "user not found"

# password matched the hashed value from the database
return "welcome guest"

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