In our previous tutorial, we built a registration form and handled form submission with a controller. Now, let's take the next step and implement complete user authentication using Laravel's built-in features.
What We'll Cover Today
- Running Laravel's default migration for authentication
- Understanding the User model and database structure
- Completing our registration functionality
- Adding login/logout features
- Understanding Laravel's security features
Step 1:Running the Default Authentication Migration
To implement user authentication, the first thing we need is a secure place to store user information, like names, emails, and, most importantly hashed passwords.
Fortunately, Laravel includes the entire necessary database structure by default. We just need to run the standard migration command to create the tables.
1.The Migration Command
Open your terminal in the root directory of your Laravel project and run the following command:
php artisan migrate
2.What Just Happened?
When you run php artisan migrate on a new project, Laravel looks in the database/migrations directory and executes any pending migration files. The key file for authentication is the one that creates the users table.
This table is foundational for Laravel's authentication system and includes all columns we need.
3.Verification
To confirm the table was created successfully, you can check by using a database management tool (like Heidi). You should see a new users table ready to accept registration data.
With the database structure in place, we can now move on to the code that interacts with this table
Step 2:Understanding the User Model and Database Structure
In Laravel, the bridge between your application code and your database tables is called an Eloquent Model. For authentication, this role is filled by the default User model.
1.Locating the User Model
The default User model is located in:
app/Models/User.php
2.The Model's Role
The User.phpfile is an essential class that does three critical things:
-
Connects to the Table:By default, Laravel models follow a naming convention:a singular model name (
User) is mapped to a plural table name (users). TheUsermodel knows exactly how to read and write data to theuserstable we created in Step 1. -
Enables Eloquent Features:This model gives you access to Laravel's powerful query builder, Eloquent ORM. Instead of writing raw SQL, you can use clean PHP methods like
User::all()orUser::create([...]). -
Implements Authentication Traits:You'll notice the
Usermodel uses theIlluminate\Foundation\Auth\Userclass and theHasApiTokens,Notifiable, andHasFactorytraits. These are built-in Laravel features that handle password hashing, session management, and other security requirements.
3.Key Model Properties
Two properties within the User.php file are important to understand for security and bulk actions:
-
$fillable:This array defines the columns in theuserstable that can be mass-assigned(i.e., filled in a single operation, like a form submission).
protected $fillable = [
'name',
'email',
'password', // We'll use this in the next step!
];
-
$hidden:This array specifies any attribute that should not be visible when the model is converted to an array or JSON(like when returning user data in an API response).
protected $hidden = [
'password', // Crucial: Keeps the hashed password private
'remember_token',
];
In the next step, we'll use the $fillable fields on this User model to complete our registration process and actually save a new user to the database.
Step 3:Completing Our Registration Functionality
The core of secure registration is taking the data submitted from the form, validating it, and then saving it to the users table while ensuring the password is securely hashed.
1.Update the Registration Controller
You'll need to modify the method in your registration controller (e.g., RegisteController.php) that handles the POST request from the form.
We will use the User model and the Hash facade to save the data.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Hash; // Import the Hash facade
class RegisterController extends Controller{
public function register(Register $register){
$incomingValues = $request->validate([
'name' => ['required','min:3', 'max:255'],
'email' => ['required','email',Rule::unique('users','email')]
'password' => ['required','min:8'],
])
$user = User::create([
'name' => $incomingValues['name'],
'email' => $incomingValues['email'],
'password' => Hash::make($incomingValues['password']),//Hashing the password before storing it
]);
auth()->login($user);//Log the user in immediately
return redirect('/');
}
}
Key Takeaways from the Code
-
Hash::make($request->password):This is the most important part! Never store raw passwords. Laravel's Hash facade uses strong, one-way encryption to hash the password.The actual password is not recoverable, which keeps your users secure even if your database is compromised. -
User::create([...]):This uses the Eloquent Model's mass assignment feature(which relies on the$fillableproperty we discussed in Step 2) to quickly create and save the new user record.
Now, a user successfully submitting the registration form will create a secure record in your database. Next, we'll leverage this secure record to implement the full login and logout flow.
Testing the Registration
- Fill out your registration form
- Submit and check your database, you should see a new user with hashed password
- You should be automatically logged in and redirected
Step 4:Adding Login and Logout Features
Laravel makes handling sessions and authenticating users remarkably simple using the Auth facade.
1.Implementing the Login Logic(Session Creation)
The login process involves two main steps: displaying the form and processing the credentials.
A. The Login Controller Method
You'll need a method in your controller (e.g., LoginController.php) to handle the form submission. We use the Auth::attempt() method, which automatically does the heavy lifting:
- It fetches a user from the database based on the email(or whatever field you set as the authentication identifier).
- It takes the submitted, unhashed password and compares it against the hashed password stored in the database.
- If the credentials match, it creates a secure session for the user.
//In your LoginController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; //Import the Auth facade
//..inside the class ...
public function authenticate(Request $request){
//1.Validate the input fields
$credentials = $request->validate([
'email' => ['required','email'],
'password' => ['required'],
]);
//2.Attempt to log the user in
if(Auth::attempt($credentials)){
$request->session()->regenerate();
return redirect('/')->intended('/dashboard');
}
}
-
Auth::attempt($credentials):The magic happens here. It tries to find a user matching the email and verifies the password hash. -
$request->session()->regenerate():This is a security best practice in Laravel to prevent session fixation attacks after a successful login. -
redirect()->intended('/dashboard'):This is another helpful Laravel feature. It redirects the user to the URL they were trying to access before they were sent to the login page
2.Implementing the Logout Logic(Session Destruction)
Logging a user out is much simpler. It involves destroying the user's current session and revoking their authentication status.
A. The Logout Controller Method
You can place this in the same LoginController.php or a separate LogoutController.php:
//In your LoginController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
//...inside the class...
public function logout(Request $request)
{
//1.Logout the user
Auth::logout();
//2.Invalidate the existing session
$request->session()->invalidate();
//3.Regenerate the CSRF token
$request->session()->regenerateToken();
//4.Redirect to the homepage or login page
return redirect('/');
}
-
Auth::logout():Clears all authentication information from the current session. -
$request->session()->invalidate():Invalidates the current session, ensuring it can't be reused -
$request->session()->regenerateToken():Regenerates the Cross-Site Request Forgery (CSRF) token for the next user session.
3.Setting up Routes
Finally, make sure you have the routes defined to point to these new controller methods:
\\In your routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
Route::get('/', function () {
return view('home');
});
Route::post('/register', [UserController::class, 'register']);
Route::post('/logout', [LoginController::class,'logout']);
Route::post('/login', [LoginController::class,'login']);
Note:We use a POST route for logout, not a GET. This is another security best practice to prevent attackers from tricking users into logging out via a simple link click.
Step5: Understanding Laravel's Security Features
We have built user authentication, but we have also implemented several critical, behind the scenes security measures simply by using Laravel's built-in tools. This step reassures you, the readers, about the robustness of this application.
1. Password Hashing
As we discussed in Step 3, we use Hash::make() instead of storing raw passwords. This is the single most important security feature.
- How it works:Laravel uses a modern, slow hashing algorithm which takes the user's password and transforms it into a long, non-reversible string.
- The Benefit:If your database is ever compromised, the attacker only gets impossible-to-decrypt hash strings, not your users' actual passwords. This protects both your application and your users' security on other websites.
2. Session Fixation Prevention
Laravel automatically handles the creation and management of user sessions, including defending against one common attack:
- Session Fixation:This is an attack where a hacker tricks a user into logging in with a session ID the hacker already knows.
-
Your Defense:When you include
request()->session()->regenerate();in yourloginmethod, you instructed Laravel to generate a brand new, unique session ID after a successful login. This instantly destroys the old, potentially compromised session ID, rendering any hacker's pre-set ID useless.
3.Cross-Site Request Forgery (CSRF) Protection
If you're using Laravel forms(or using @csrf blade directive), you already have powerful protection against CSRF.
- What is CSRF?It's an attack where a hacker tries to force a logged-in user to submit a malicious request(like changing their password or making a purchase) without their knowledge.
-
Your Defense:Laravel requires a hidden, unique CSRF token to be included with every non-GET request (like
POST,PUT, etc.). If the token doesn't match, Laravel rejects the request automatically. This token is tied to the user's secure session, preventing unauthorized external requests.
4.Input Sanitization
While you must still validate your input (which we did), Laravel's framework and its ORM, Eloquent, are inherently designed to protect against SQL Injection.
-
SQL Injection:This is an attack where a user inputs malicious SQL code into a form field (like entering
' OR 1=1; --into a username field) to manipulate your database queries. -
Your Defense:When you use Eloquent commands like
User::create($incomingFields), Laravel automatically sanitizes all input, treating it strictly as data and not as executable code. This makes SQL injection attacks virtually impossible through Eloquent.
Wrapping Up: What We've Accomplished
We have successfully integrated complete user authentication into our application. By following these five steps, we now have a secure functional system:
- Ran the default migration to create the essential
userstable. - Utilized the
UserEloquent Model as the primary interface to our database. - Secured registration using
Hash::make()to encrypt passwords. - Implemented smooth Login and Logout with the
Authfacade. - Gained powerful, passive security from Laravel, including CSRF and SQL Injection protection.
We are now ready to build out the features of our application with confidence, knowing the identity and security of our users are handled.
Top comments (0)