How to Hash Passwords the Right Way in Laravel

Updated: January 16, 2024 By: Guest Contributor Post a comment

Introduction

Password hashing is a critical aspect of securing user credentials within an application. Laravel, a powerful PHP framework, makes this task straightforward and secure with its built-in functionalities. In this tutorial, we will explore the correct methods of hashing passwords, leveraging the robust features of Laravel to enhance the security of your applications.

Understanding Laravel’s Hashing System

Laravel includes a variety of hashing drivers, with bcrypt as the default. Bcrypt is widely considered a secure hashing algorithm, as it incorporates salt to protect against rainbow table attacks and is adaptive, meaning the cost factor can be increased as hardware capabilities improve.

Configuring Hashing Settings

In your Laravel application’s config/hashing.php file, you can configure the default hashing driver and options. Adjusting the 'bcrypt' options will allow you to specify the 'rounds', adjusting the computational cost of the hash generation.

<?php

return [
    'driver' => 'bcrypt',
    'bcrypt' => [
        'rounds' => 10,
    ],
    'argon' => [
        'memory' => 1024,
        'threads' => 2,
        'time' => 2,
    ],
];

Basic Usage of Hashing Passwords

To hash a password in a Laravel controller, you might do something similar to the following:

use Illuminate\Support\Facades\Hash;

//...

public function store(Request $request)
{
    $password = $request->input('password');
    $hashedPassword = Hash::make($password);

    // Save the hash to the user model
    $user = new User;
    $user->password = $hashedPassword;
    $user->save();
}

This code takes a plain text password from the request and creates a hash using the Hash::make method, which then can be saved to the database.

Check Passwords Against the Hash

When a user attempts to log in, you can verify the entered password against the stored hash with the Hash::check function:

//...

public function login(Request $request)
{
    $user = User::where('email', $request->input('email'))->first();

    if ($user && Hash::check($request->input('password'), $user->password)) {
        // Login the user
    } else {
        // Handle failed login attempt
    }
}

Rehashing

Laravel also provides a convenient way to rehash passwords when parameters in the configuration change, ensuring they remain secure over time:

//...

if (Hash::needsRehash($user->password)) {
    $user->password = Hash::make($request->input('password'));
    $user->save();
}

Hashing Via Events and Observers

For a more automatic approach, consider using Eloquent’s event system. You could listen for the 'creating' or 'updating' events on the user model to automatically hash passwords upon user creation or update.

use App\Models\User;
use Illuminate\Support\Facades\Hash;

User::creating(function ($user) {
    $user->password = Hash::make($user->password);
});

Advanced Password Hashing with Argon2

Laravel offers Argon2 for hashing, which is considered more secure but requires PHP 7.2.0 or higher. To use Argon2, change the driver in your config/hashing.php file to ‘argon’ and adjust the options appropriately.

'driver' => 'argon',
'argon' => [
    // Configuration options
],

Customizing the Hashing Process

If the built-in options don’t meet your needs, you can create custom hash drivers by implementing the Illuminate\Contracts\Hashing\Hasher interface and registering it within a service provider.

Conclusion

Understanding and properly implementing password hashing is key to providing secure authentication in your applications. Laravel simplifies this process, offering robust, flexible methods to ensure that user passwords are safely managed. By following the best practices detailed in this tutorial, you can ensure that the user credentials are well-protected.