How Do I Handle Passwords Securely in My App?
You built an app with Claude, ChatGPT, Bolt, or Lovable that has user accounts, and at some point you realised you are responsible for handling people's…
You built an app with Claude, ChatGPT, Bolt, or Lovable that has user accounts, and at some point you realised you are responsible for handling people’s passwords. This feels weighty, and it should. Handling passwords badly is one of the most common causes of data breaches, and the consequences for your users can be serious. The good news is that handling passwords correctly is straightforward if you know the rules. Here is exactly what to do.
The Golden Rule: Never Store Passwords in Plain Text
If your database is ever breached and attackers can read it, and passwords are stored as plain text, every user’s password is immediately compromised. Since most people reuse passwords, that means their email, banking, and other accounts may also be at risk.
The correct approach is to store a hashed version of the password, not the password itself.
A one-sentence definition: password hashing is a one-way process that converts a password into a fixed-length string that cannot be reversed, so even if someone reads your database, they cannot recover the original passwords.
How Hashing Works
When a user sets their password, your app runs it through a hashing function. The hash, not the password, is stored in your database.
When a user logs in, your app hashes the password they just typed and compares it to the stored hash. If they match, the password is correct. At no point does your app store or transmit the actual password.
You never store the password. You only store its hash. If someone reads your database, they see unreadable hashes, not passwords.
The Right Hashing Algorithm: bcrypt
Not all hashing algorithms are suitable for passwords. MD5 and SHA-1, for example, are fast algorithms that can be brute-forced quickly.
bcrypt is the standard recommendation for password hashing. It is deliberately slow, making brute-force attacks impractical. It also includes a salt automatically, which is a random value added to each password before hashing to prevent pre-computed attacks.
In Python, use the bcrypt library or passlib. In JavaScript and Node.js, use bcrypt or argon2. Ask your AI: “Can you implement password hashing in my app using bcrypt? I want user passwords to be hashed before storing and properly compared during login.”
Let an Auth Service Handle It Instead
The simplest and most reliable approach is to not handle passwords yourself at all.
Authentication services like Clerk, Auth0, and Supabase Auth handle password storage, hashing, and security for you. They implement best practices, stay updated as security requirements change, and remove the risk of you making a mistake.
If your app does not yet have authentication, starting with one of these services is strongly recommended over building your own. We covered this in the OAuth and two-factor authentication posts earlier in this series.
If you are already handling passwords yourself and want to switch to a managed service, ask your AI: “I currently store user passwords in my own database. Can you help me migrate to [Clerk / Auth0 / Supabase Auth] so that authentication is handled by a managed service?”
Other Password Security Rules
Minimum length. Enforce a minimum password length of at least eight characters. Twelve or more is better.
Do not have silly complexity rules. Requiring exactly one capital letter, one number, and one symbol results in weaker, more predictable passwords. Longer passwords are more secure than complex short ones.
Rate limit login attempts. After several failed login attempts, temporarily block further attempts to prevent brute-force attacks. Ask your AI: “Can you add rate limiting to my login endpoint so that after five failed attempts, the user is locked out for fifteen minutes?”
Never email passwords. If a user forgets their password, send a password reset link, not their password. Your app should not know their password.
The One Thing to Remember
Never store passwords as plain text. Use bcrypt to hash passwords before storing them. The simplest and most secure approach is to use an authentication service like Clerk, Auth0, or Supabase Auth that handles all of this for you. If you handle passwords yourself, use bcrypt, enforce minimum length, and rate limit login attempts.
Want your app with secure user authentication running reliably in production? → Snapdock
New here? These might help: What is OAuth? How “Sign In With Google” actually works. → How do I add two-factor authentication to my app? →