DEV Community

Cover image for Hash Passwords in Backend: A Guide for Every Tech Stack
Mahmudur Rahman
Mahmudur Rahman

Posted on

Hash Passwords in Backend: A Guide for Every Tech Stack

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

Enter fullscreen mode Exit fullscreen mode

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);

Enter fullscreen mode Exit fullscreen mode

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);
};

Enter fullscreen mode Exit fullscreen mode

2. Python (Flask & Django) with bcrypt (MongoDB & PostgreSQL)

Installation

pip install bcrypt pymongo psycopg2 flask-sqlalchemy

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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);
    }
}

Enter fullscreen mode Exit fullscreen mode

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);
    }
}

Enter fullscreen mode Exit fullscreen mode

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);
    }
}

Enter fullscreen mode Exit fullscreen mode

5. Golang (Gin & Fiber) with bcrypt (MongoDB & PostgreSQL)

Installation

go get golang.org/x/crypto/bcrypt

Enter fullscreen mode Exit fullscreen mode

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
}

Enter fullscreen mode Exit fullscreen mode

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!

🚀 Follow me on GitHub and Twitter for more!

Top comments (0)