I am using the cookie cutter flask app with python 3.5 and postgresql. Postgresql is running on a docker image, with no config modifications.
psql tells me that the database is utf-8. I was getting string encoding errors until I used SQLALCHEMY_NATIVE_UNICODE = True
The sqlalchemy column is:
password = Column(db.String(256 ), nullable=True)
and the postgresql encoding is UTF-8
I was getting a Value Error invalid salt in a password validation. It seems that the database value is read and then converted to bytes encoded to UTF-8 before being sent to bcrypt for hash validation. It seems that the bcrypt functions work with bytes. Maybe bcrypt does this itself, when it gets a string, and perhaps it defaults to utf-8 (the code is not explicit about providing an encoding).
Be.low is the standard code which stores the hash. It takes the value returned by bcrypt.generate_password_hash(password), but however, it gets mangled later when it gets encoded.
def set_password(self, password):
"""Set password."""
self.password = bcrypt.generate_password_hash(password)
and this fixes it:
def set_password(self, password):
"""Set password."""
self.password = bcrypt.generate_password_hash(password).decode('utf-8')
I don't really understand how this is allowed. To get this to work I decode it, and then it gets handled by "something" which expects utf-8. When I don't give it utf-8, it should be an exception, shouldn't it?
related question: flask-bcrypt - ValueError: Invalid salt