I need to login with username/password instead of email/password, but I want to keep using anvil.users.get_user() etc.
I assume I’d need to manage change password and signup myself.
To do that I need to know how the password is hashed. Is that something you can share? I can see it’s bcrypt, but crypto implementation is not my strong point; I assume I’d need to salt it somehow for your login_with_form() to work?
Is there a better way?
This is a perfect example of the flexibility of the Users service. Because a user is just a row in the Users table, I can define whatever login mechanism I like in a server function. If I added a “username” column to my Users table, I could write the following server function:
import bcrypt
@anvil.server.callable
def login_with_username(username, password):
user = app_tables.users.get(username=username)
if user is not None and \
bcrypt.hashpw(password, user['password_hash']) == user['password_hash']:
anvil.users.force_login(user)
return user
Of course, you’d then have to make up your own system for setting the username column in your table (and signing up, and resetting passwords, etc.) Unless, of course, you want to do it all from the Anvil editor, which is totally legit if you have a small user base.
This example uses the bcrypt password hash, which is the same hash used by the “Email address and password” login system in the Users service. This means you can still use the “Reset password” feature from the dropdown in the Users service:

2 Likes