Hashing

Nimbus provides bcrypt password hashing via the hash package. Hash passwords on registration, verify on login, and tune cost for your security needs.

Hash a Password

import "github.com/CodeSyncr/nimbus/hash"

func (u *User) SetPassword(plain string) error {
    h, err := hash.Make(plain)
    if err != nil { return err }
    u.PasswordHash = h
    return nil
}

Verify a Password

// hash.Check(plain, hashed) returns true if they match
if !hash.Check(password, user.PasswordHash) {
    return c.JSON(401, map[string]string{"error": "Invalid credentials"})
}

// In a login controller
func (ctrl *AuthController) Login(c *http.Context) error {
    email := c.FormValue("email")
    password := c.FormValue("password")

    var user models.User
    if err := ctrl.DB.Where("email = ?", email).First(&user).Error; err != nil {
        return c.View("auth/login", map[string]any{"error": "User not found"})
    }

    if !hash.Check(password, user.PasswordHash) {
        return c.View("auth/login", map[string]any{"error": "Invalid credentials"})
    }

    ctrl.Guard.Login(c.Request.Context(), &user)
    return c.Redirect(302, "/dashboard")
}

Custom Cost

Higher cost = slower hashing = more secure. Default is 10. Use 12+ for production:

// Custom cost (12 is ~4x slower than 10)
hashed, err := hash.MakeWithCost(plaintext, 12)

// Default cost (10)
hashed, err := hash.Make(plaintext)

API Reference

FunctionDescription
hash.Make(plain)Hash with default cost (10)
hash.MakeWithCost(plain, cost)Hash with custom bcrypt cost (4-31)
hash.Check(plain, hashed)Returns true if plain matches hashed

With Model Hooks

Auto-hash passwords using a BeforeCreate hook:

database.RegisterHooks(db, "users", database.Hooks{
    BeforeCreate: func(db *gorm.DB) {
        if u, ok := db.Statement.Dest.(*User); ok && u.PasswordHash != "" {
            hashed, _ := hash.Make(u.PasswordHash)
            u.PasswordHash = hashed
        }
    },
})