Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Password Compat Laravel Package

ircmaxell/password-compat

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require ircmaxell/password-compat
    

    Or manually include vendor/ircmaxell/password-compat/lib/password.php in your project.

  2. Verify Compatibility: Run the included version-test.php script to confirm your PHP environment supports the package. If it outputs "Pass", proceed.

  3. First Use Case: Hash a password (e.g., during user registration):

    $hashedPassword = password_hash('user_input_password', PASSWORD_BCRYPT);
    

    Verify a password (e.g., during login):

    if (password_verify('user_input_password', $hashedPassword)) {
        // Authenticate user
    }
    
  4. Key Files:

    • vendor/ircmaxell/password-compat/lib/password.php: Core functionality.
    • tests/: Reference implementation for edge cases.

Implementation Patterns

Core Workflows

  1. Password Hashing:

    • Use password_hash() with PASSWORD_BCRYPT (default) or PASSWORD_DEFAULT (aliases to PASSWORD_BCRYPT).
    • Customize cost (work factor) via the options parameter:
      $hashed = password_hash('password', PASSWORD_BCRYPT, ['cost' => 12]);
      
    • Store the hash in your database (e.g., users.password column).
  2. Password Verification:

    • Always use password_verify() for comparison:
      if (password_verify($plainPassword, $storedHash)) {
          // Success
      }
      
    • Never implement custom verification logic (e.g., comparing hashes directly).
  3. Password Upgrading:

    • Use password_needs_rehash() to check if a hash should be upgraded (e.g., due to cost changes):
      if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ['cost' => 12])) {
          $newHash = password_hash($plainPassword, PASSWORD_BCRYPT, ['cost' => 12]);
          // Update database
      }
      
  4. Integration with Laravel:

    • Hashing: Use Laravel’s built-in Hash facade (which internally uses password_hash):
      use Illuminate\Support\Facades\Hash;
      $hashed = Hash::make('password'); // Uses password_compat under the hood
      
    • Verification: Similarly, Hash::check() leverages password_verify:
      if (Hash::check($request->password, $user->password)) { ... }
      
    • Custom Rules: Extend Laravel’s validation rules for password strength:
      use Illuminate\Validation\Rules\Password;
      $request->validate([
          'password' => ['required', new Password(min: 8, rules: Password::DEFAULT_RULES)],
      ]);
      
  5. Migrations:

    • When upgrading from legacy hashes (e.g., MD5, SHA1), rehash all passwords using password_hash() and store the new hashes.

Advanced Patterns

  1. Multi-Factor Hashing:

    • Combine with other libraries (e.g., paragonie/sodium_compat) for hybrid hashing schemes:
      $salt = random_bytes(16);
      $hash = password_hash($password . $salt, PASSWORD_BCRYPT);
      // Store $salt separately
      
  2. Rate Limiting:

    • Pair with Laravel’s throttle middleware to prevent brute-force attacks on password verification.
  3. Audit Logging:

    • Log failed verification attempts (without storing plaintext passwords):
      if (!password_verify($input, $hash)) {
          Log::warning('Failed password attempt for user ' . $user->id);
      }
      
  4. Testing:

    • Use Laravel’s Hash facade in tests:
      $hashed = Hash::make('password');
      $this->assertTrue(Hash::check('password', $hashed));
      
    • Mock password_verify in unit tests if needed:
      $mock = Mockery::mock('alias:password_verify');
      $mock->shouldReceive('verify')->andReturn(true);
      

Gotchas and Tips

Pitfalls

  1. Unsupported PHP Versions:

    • Issue: Using PHP < 5.3.7 (or unsupported backports) will return false for all password_* functions.
    • Fix: Upgrade PHP or avoid password_compat entirely. Test with version-test.php.
  2. False Positives in Verification:

    • Issue: password_verify() may return true for similar but incorrect passwords due to rainbow table resistance.
    • Fix: Enforce strong password policies (e.g., Laravel’s Password rule) and use multi-factor authentication.
  3. Cost Parameter Misuse:

    • Issue: Setting an excessively high cost (e.g., >15) can degrade performance.
    • Tip: Default to PASSWORD_BCRYPT (cost=10) unless profiling shows a need for adjustment.
  4. Legacy Hash Migration:

    • Issue: Directly comparing legacy hashes (e.g., MD5) with password_verify will fail.
    • Fix: Rehash all passwords during migration:
      $user->password = password_hash($user->password, PASSWORD_BCRYPT);
      $user->save();
      
  5. Database Storage:

    • Issue: Storing hashes in plaintext or unencrypted columns.
    • Fix: Use Laravel’s encrypt or encryptString for additional protection (though not required for password_hash).

Debugging

  1. Failed Hashing:

    • Symptom: password_hash() returns false.
    • Debug:
      • Check PHP version (php -v).
      • Verify password.php is autoloaded (e.g., via Composer).
      • Ensure no custom password_hash overrides exist.
  2. Verification Issues:

    • Symptom: password_verify() always returns false.
    • Debug:
      • Compare plaintext and stored hash lengths (should differ).
      • Test with a known good hash:
        $testHash = password_hash('test123', PASSWORD_BCRYPT);
        password_verify('test123', $testHash); // Should return true
        
  3. Performance Bottlenecks:

    • Symptom: Slow password verification during login.
    • Debug:
      • Profile with PASSWORD_BCRYPT cost=10 (default). Adjust cost if needed.
      • Consider caching verified sessions (Laravel’s remember_token).

Configuration Quirks

  1. Laravel-Specific:

    • Hash Driver: Laravel defaults to bcrypt (uses password_compat if needed). Override in config/hash.php:
      'driver' => 'bcrypt',
      'bcrypt' => [
          'rounds' => 12, // Maps to `cost` in password_hash
      ],
      
    • Custom Cost: Extend the Hash facade to enforce project-wide defaults:
      // app/Providers/AppServiceProvider.php
      Hash::extend('custom', function($app) {
          return new class {
              public function make($value, array $options) {
                  return password_hash($value, PASSWORD_BCRYPT, ['cost' => 12]);
              }
              public function check($value, $hashedValue, array $options) {
                  return password_verify($value, $hashedValue);
              }
          };
      });
      
  2. Environment-Specific Costs:

    • Dynamically adjust cost based on server specs:
      $cost = (strpos(PHP_OS, 'WIN') === false) ? 12 : 10; // Higher cost on Linux
      $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => $cost]);
      

Extension Points

  1. Custom Hash Algorithms:

    • Extend password_compat by adding new algorithms (e.g., Argon2 via defuse/php-encryption):
      // lib/extended_password.php
      require 'vendor/ircmaxell/password-compat/lib/password.php';
      function password_hash_argon2($password, $options) {
          // Custom implementation
      }
      
  2. Pre-Hash Transformations:

    • Add logic before hashing (e.g., appending a pepper):
      $pepper = config('app.password_pepper');
      $hashed = password_hash($password . $pepper, PASSWORD_BCRYPT);
      
  3. Post-Verification Actions:

    • Hook into verification failures (e.g., trigger CAPTCHA):
      if (!password_verify($input, $hash
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware