Overview Modern security standards require more than just a strong password. Laravel now addresses this by providing out-of-the-box support for Two-Factor Authentication (2FA) across its official starter kits. This implementation significantly hardens user accounts by requiring a secondary time-based one-time password (TOTP) from an authenticator app, making it exponentially harder for malicious actors to compromise accounts through credential stuffing or phishing. Prerequisites To follow this guide, you should have a basic understanding of the PHP ecosystem and Composer. Familiarity with terminal commands and local development environments is necessary to scaffold the application. Key Libraries & Tools - **Laravel Fortify**: The backend-agnostic authentication engine that handles the logic for 2FA, password resets, and registration. - **Livewire**: A full-stack framework for Laravel that simplifies building dynamic interfaces without leaving the comfort of Laravel. - **Google Authenticator**: A mobile application used to scan QR codes and generate TOTP codes. - **Pest**: A testing framework frequently used in these starter kits to ensure authentication flows remain stable. Code Walkthrough Setting up 2FA begins during the application scaffolding phase. When you run the installation command, you select your preferred stack: ```bash Creating a new project with Livewire and built-in auth laravel new security-demo --livewire --auth ``` Once the application is running, the user navigates to the **Settings** profile page. Laravel generates a unique secret key and a corresponding QR code. After scanning this with an app like Google Authenticator, the user must provide a valid code to confirm the link. This "confirmation" step is critical; it ensures the user hasn't accidentally locked themselves out by enabling 2FA without a working device. Syntax Notes Configuration for these features lives in the `config/fortify.php` file. You will notice an array of features that can be toggled to customize the security experience: ```python 'features' => [ Features::registration(), Features::resetPasswords(), Features::twoFactorAuthentication([ 'confirm' => true, 'confirmPassword' => true, ]), ] ``` The `confirm` key requires the user to verify a code before the feature is fully active, while `confirmPassword` forces a password challenge before a user can even view their 2FA settings. Tips & Gotchas Always verify that your application's `APP_URL` in the `.env` file is set correctly. The QR code generator uses this URL to label the account inside the authenticator app. If it is left as 'localhost' while in production, your users will have a hard time identifying which code belongs to your service.
Livewire
Software
- Oct 9, 2025
- Sep 4, 2025
- Nov 7, 2024
- Oct 31, 2024
- Sep 3, 2024
The Laravel ecosystem moves fast, and the latest 11.20 release proves that even small helper methods can significantly clean up your test suite and database queries. These updates focus on precision, ensuring your application doesn't just work, but behaves exactly as expected under the hood. Granular Header Control with WithoutHeader Testing HTTP requests often involves setting global headers, but sometimes you need to isolate a specific call. While we've long had `withHeader`, the new `withoutHeader` method allows you to strip away specific headers for a single test. This is vital when testing middleware that should fail if a specific token or content-type is missing. Instead of rebuilding your entire request state, you simply tell Laravel what to ignore. Enforcing Strict API Contracts One of the most powerful additions is `assertExactJsonStructure`. Standard JSON assertions often pass as long as the required keys exist, even if the API returns twenty extra fields. In a production environment, leaking internal model attributes is a security risk. By using `assertExactJsonStructure`, the test fails if your response contains any keys outside of your defined schema. It forces your API to remain lean and strictly documented. Seamless HTML Assertions Borrowing a page from the Livewire playbook, Laravel now includes `assertSeeHtml`. Testing raw HTML strings previously required passing `false` as a second argument to `assertSee` to prevent escaping. The new helper—along with its counterparts `assertSeeHtmlInOrder` and `assertDontSeeHtml`—makes the code more readable and intent-focused. It’s a cleaner way to verify that your UI components render specific tags correctly. Expanding Query Logic with WhereNone On the database side, Eloquent continues to improve its readability. Following the introduction of `whereAny`, we now have `whereNone`. This method allows you to verify that a search term does not exist across a collection of columns. It eliminates the need for messy nested `where` and `orWhere` callbacks, keeping your repository patterns clean and your logic easy to follow at a glance.
Aug 8, 2024Overview of the Inertia Approach Building single-page applications (SPAs) often feels like managing two separate worlds: a complex JavaScript frontend and a robust PHP backend. Usually, this requires building a messy REST API and managing client-side routing, which adds significant overhead. Inertia.js solves this by acting as an adapter rather than a framework. It allows you to build fully client-side rendered SPAs using classic server-side routing and controllers. You get the snappy feel of a modern web app without the pain of manual state synchronization or token-based authentication. Prerequisites Before diving into the code, ensure you have a firm grasp of Laravel fundamentals, particularly routing and controllers. Since Inertia.js lets you use your favorite frontend tools, you should be comfortable with either Vue.js or React. You will also need Node.js and Composer installed on your local machine to manage dependencies. Key Libraries & Tools - **Laravel Installer**: The command-line utility for bootstrapping new projects. - **Laravel Breeze**: A minimal starter kit that provides a perfect starting point for Inertia.js projects. - **Inertia Adapters**: Specialized packages for Vue.js or React that bridge the gap between the backend and the frontend. Code Walkthrough: Data Exchange In a standard app, a link click reloads the whole page. Inertia.js intercepts these clicks and performs an AJAX request instead. On the backend, your controller looks surprisingly familiar: ```php use Inertia\Inertia; public function index() { return Inertia::render('Dashboard', [ 'users' => User::all(), ]); } ``` Instead of returning a Blade view, we use `Inertia::render`. This sends a JSON response containing the component name ('Dashboard') and the data (props). On the frontend, Inertia.js receives this data and swaps the current page component with the new one dynamically. Syntax Notes & Best Practices Always use the `<Link>` component provided by the Inertia.js library rather than standard `<a>` tags. Standard tags trigger a full browser refresh, defeating the purpose of the SPA. ```javascript import { Link } from '@inertiajs/vue3' <Link href="/users">View Users</Link> ``` Tips & Gotchas Don't try to use Inertia.js for public-facing websites where SEO is the top priority unless you implement Server Side Rendering (SSR). For internal dashboards and complex SaaS products, however, it shines. Remember that because Inertia.js shares the same session as your Laravel backend, you don't need to worry about OAuth or JWT for internal navigation. Use the standard Laravel auth guards you already know.
Jul 4, 2024Overview In a growing application, returning consistent data formats across dozens of controllers is a maintenance nightmare. Laravel provides **Response Macros** as a solution to this fragmentation. Macros allow you to extend core framework classes with custom methods, effectively creating a domain-specific language for your responses. Instead of manually structuring JSON arrays for every endpoint, you define the schema once and invoke it everywhere. This ensures that every client—be it a mobile app or a frontend framework—receives a predictable `status` and `data` structure. Prerequisites To follow this guide, you should have a solid grasp of **PHP** and the **Laravel** framework. Familiarity with **Service Providers**, **Facades**, and **RESTful APIs** is essential. You should also understand how closures work in PHP, as they form the logic of the macro itself. Key Libraries & Tools * **Laravel Framework**: The core PHP framework providing the `Response` facade. * **Laravel Idea**: A PHPStorm plugin that provides autocompletion for macros. * **Jetstream & Livewire**: Tools used for session flash notifications and frontend interaction. Code Walkthrough Defining the Macro You typically define macros in the `boot` method of a `ServiceProvider`. Here, we extend the Response facade with a custom `api` method. ```python Response::macro('api', function ($data) { return Response::json([ 'status' => 'success', 'data' => $data, ]); }); ``` Implementing in Controllers Once defined, you replace messy array structures with a clean, expressive method call. This removes boilerplate and prevents naming inconsistencies like switching between `data` and `results` keys. ```python public function index() { return response()->api(Podcast::all()); } ``` Advanced Notification Macros Macros aren't limited to JSON. You can combine session flashing and redirects into a single call, such as `backWithNotification`, to handle form submissions gracefully. ```python Response::macro('backWithNotification', function ($message) { session()->flash('flash.banner', $message); session()->flash('flash.bannerStyle', 'success'); return back(); }); ``` Syntax Notes Laravel uses the **Macroable** trait to enable this functionality. When you call `Response::macro()`, you are registering a closure into a static array that the framework checks whenever a non-existent method is called on the facade. Note that we use **Type Hinting** within the closure to ensure the data passed matches our expected format. Practical Examples * **API Standardization**: Ensuring all mobile app endpoints return a `count` or `meta` field automatically. * **UI Consistency**: Creating a `response()->error($message)` macro that always returns a 422 status code and a specific error payload. Tips & Gotchas Avoid putting heavy business logic inside a macro; keep them focused on **formatting and delivery**. If you use IDEs like PHPStorm, remember that macros are dynamic. You may need a helper tool like Laravel Idea to get proper autocompletion and avoid "method not found" warnings in your editor.
Apr 4, 2024The Architecture of Choice in Laravel 8 Laravel 8 marks a significant shift in how we approach the front-end, or more accurately, how we don't. By default, the framework remains entirely agnostic. When you run `laravel new`, you get Blade templates and nothing else. No Tailwind, no Vue, and certainly no forced architectural patterns. This is intentional. The goal is to provide a clean slate while offering powerful, optional scaffolding for those who want to move faster. Much of the recent noise in the community suggests that using tools like Inertia.js or Livewire is a requirement or a "betting of the farm" on immature tech. This fundamentally misunderstands what these tools do. Inertia isn't a massive framework; it's a bridge that lets you use Laravel's routing to hydrate Vue components. It keeps you productive by removing the need for a separate API repository, which is often a productivity killer for solo developers and small teams. Demystifying the Starter Kits: Breeze and Jetstream To understand where you should start, you have to look at the complexity of your requirements. Laravel Breeze represents the baseline. It is a simple, minimal implementation of all Laravel's authentication features—login, registration, password reset—using simple controllers and routes that you can actually see and modify in your app. It’s the spiritual successor to the old `make:auth` command, but modernized with Tailwind. Laravel Jetstream sits at the other end of the spectrum. It is essentially the free, open-source core of what used to be Laravel Spark. We moved all the non-billing features—team management, two-factor authentication, and API token management—out of Spark and into Jetstream. It uses Laravel Fortify as its headless backend. This means Jetstream handles the UI (via either Inertia or Livewire), while Fortify handles the heavy lifting of authentication logic in the background. Passport vs. Sanctum: Choosing Your API Guard The most persistent confusion in our ecosystem revolves around Laravel Passport and Laravel Sanctum. The decision tree is actually quite simple: if you need to build a full OAuth2 server—the kind where users can "Sign in with Your App" on third-party sites—you need Passport. It is a robust, compliant implementation built on the league/oauth2-server. However, most developers don't actually need OAuth2. They just need to secure an API or a Single Page Application (SPA). For these use cases, Passport is a sledgehammer. Sanctum was built to solve the "API for myself" problem. It provides a lightweight way to issue personal access tokens and, more importantly, a way to authenticate SPAs using secure, stateful cookies. The Secret Sauce of SPA Authentication Sanctum's true power lies in its ability to toggle between token-based and cookie-based authentication. When your SPA sits on the same top-level domain as your Laravel API, you shouldn't be messing with JWT storage in `localStorage`. It’s insecure and unnecessary. Instead, Sanctum allows your SPA to call a login endpoint, which uses standard Laravel session guards to issue a secure HTTP-only cookie. The browser then handles that cookie automatically for every subsequent request. If a request comes in without a cookie, the Sanctum guard looks for a `Bearer` token in the header. This dual-layer approach allows the same API routes to serve your first-party SPA via cookies and third-party mobile apps or SDKs via tokens. It’s the most secure and streamlined way to handle modern web authentication without the overhead of a full OAuth2 handshake. Community Dynamics and Open Contributions There is a narrative that the Laravel ecosystem is a closed circle, but the data proves otherwise. With over 2,800 contributors, the "inner circle" is massive. Developers like Paris Malhotra prove that anyone can show up, submit high-quality pull requests to core packages like Laravel Horizon, and get them merged. This isn't about personal friendships; it's about labor and merit. People like Caleb Porzio and Jonathan Reinink earned their status through hundreds of hours of free work to make the ecosystem better. We want people who bring positive energy and a desire to make programming more enjoyable. If you're here to armchair quarterback, you're missing the point of what we're building.
Dec 31, 2020