Security is a top priority in any application, and properly hashing passwords is a fundamental practice. In this post, we will explore how to securely hash passwords in various backend technologies, covering different programming languages, frameworks, and databases (SQL & NoSQL).
Why Hash Passwords?
Storing plain-text passwords is a major security risk. Hashing transforms a password into a fixed-length, irreversible string. When a user logs in, their input password is hashed again and compared to the stored hash.
Commonly Used Hashing Algorithms
- bcrypt (recommended for most cases)
- Argon2 (recommended for modern security needs)
- PBKDF2 (used in many enterprise applications)
- SHA-256/SHA-512 (faster but less secure without salting and stretching)
1. Node.js (Express.js) with bcrypt (MongoDB & MySQL)
Installation
npm install bcrypt
MongoDB Example
const bcrypt = require("bcrypt");
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
// Hash password before saving
userSchema.pre("save", async function (next) {
if (!this.isModified("password")) return next();
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});
// Compare password during login
userSchema.methods.comparePassword = async function (inputPassword) {
return await bcrypt.compare(inputPassword, this.password);
};
const User = mongoose.model("User", userSchema);
MySQL Example (Using Sequelize)
const bcrypt = require("bcrypt");
const { Sequelize, DataTypes, Model } = require("sequelize");
const sequelize = new Sequelize("database", "user", "password", { dialect: "mysql" });
class User extends Model {}
User.init(
{
username: DataTypes.STRING,
password: DataTypes.STRING,
},
{ sequelize, modelName: "User" }
);
User.beforeCreate(async (user) => {
user.password = await bcrypt.hash(user.password, 10);
});
User.prototype.comparePassword = async function (inputPassword) {
return await bcrypt.compare(inputPassword, this.password);
};
2. Python (Flask & Django) with bcrypt (MongoDB & PostgreSQL)
Installation
pip install bcrypt pymongo psycopg2 flask-sqlalchemy
MongoDB Example (Flask)
import bcrypt
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
db = client["users_db"]
users = db["users"]
def hash_password(password):
salt = bcrypt.gensalt()
return bcrypt.hashpw(password.encode('utf-8'), salt)
def check_password(hashed_password, input_password):
return bcrypt.checkpw(input_password.encode('utf-8'), hashed_password)
password = "my_secure_password"
hashed_pw = hash_password(password)
users.insert_one({"username": "test", "password": hashed_pw})
print(check_password(hashed_pw, "wrong_password")) # False
print(check_password(hashed_pw, "my_secure_password")) # True
PostgreSQL Example (Django)
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth.hashers import make_password, check_password
class CustomUser(AbstractUser):
password = models.CharField(max_length=128)
def save(self, *args, **kwargs):
if not self.password.startswith("pbkdf2_sha256$"):
self.password = make_password(self.password)
super().save(*args, **kwargs)
def verify_password(self, input_password):
return check_password(input_password, self.password)
3. Java (Spring Boot) with BCrypt (MySQL & MongoDB)
Maven Dependency
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.6.2</version>
</dependency>
MongoDB Example
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Document(collection = "users")
public class User {
@Id
private String id;
private String username;
private String password;
public void setPassword(String password) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
this.password = encoder.encode(password);
}
public boolean checkPassword(String inputPassword) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder.matches(inputPassword, this.password);
}
}
MySQL Example (Spring Boot JPA)
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import javax.persistence.*;
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
public void setPassword(String password) {
this.password = new BCryptPasswordEncoder().encode(password);
}
public boolean checkPassword(String inputPassword) {
return new BCryptPasswordEncoder().matches(inputPassword, this.password);
}
}
4. PHP (Laravel) with Hash Facade (MySQL)
Hashing in Laravel Model
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
protected $fillable = ['name', 'email', 'password'];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
public function checkPassword($password)
{
return Hash::check($password, $this->password);
}
}
5. Golang (Gin & Fiber) with bcrypt (MongoDB & PostgreSQL)
Installation
go get golang.org/x/crypto/bcrypt
MongoDB Example
package main
import (
"golang.org/x/crypto/bcrypt"
"fmt"
)
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes), err
}
func checkPassword(hashedPassword, password string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
return err == nil
}
func main() {
password := "securepass"
hashed, _ := hashPassword(password)
fmt.Println(checkPassword(hashed, "wrongpass")) // False
fmt.Println(checkPassword(hashed, "securepass")) // True
}
Final Thoughts
- Use bcrypt or Argon2 instead of simple hash functions like SHA-256.
- Always hash passwords before storing them in databases.
- Use strong salting & iteration rounds to slow down brute-force attacks.
- Avoid storing plain-text passwords, even temporarily.
This guide should help you securely hash passwords in any backend stack!
Top comments (0)