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

Fortify Laravel Package

laravel/fortify

Frontend-agnostic authentication backend for Laravel. Provides endpoints and services for registration, login, password reset, email verification, and two-factor authentication. Used by Laravel Starter Kits; you bring the UI (Blade, Inertia, SPA, etc.).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/fortify
    

    Publish the configuration and migrations:

    php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
    php artisan migrate
    
  2. Configure Auth: In config/auth.php, set the default guard to web (or your preferred guard):

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
    
  3. Register Fortify: Add Fortify to your AppServiceProvider's boot() method:

    use Laravel\Fortify\Fortify;
    
    public function boot()
    {
        Fortify::createUsersUsing(app(\Illuminate\Contracts\Auth\Registrar::class));
    }
    
  4. First Use Case: Use the Login controller to handle authentication:

    use Laravel\Fortify\Http\Controllers\AuthenticatedSessionController;
    
    Route::post('/login', [AuthenticatedSessionController::class, 'store']);
    

Key Files to Explore

  • Controllers: app/Http/Controllers/AuthenticatedSessionController.php (login/logout)
  • Requests: app/Http/Requests/AuthenticatedSessionRequest.php (validation rules)
  • Middleware: app/Http/Middleware/EnsureEmailIsVerified.php (email verification)
  • Views: resources/views/auth/ (if using Blade; Fortify is frontend-agnostic)

Implementation Patterns

Core Workflows

1. Authentication Flow

  • Login/Logout: Use AuthenticatedSessionController for handling login/logout requests. Fortify automatically:

    • Validates credentials via AttemptToAuthenticate.
    • Redirects based on redirectIf() logic (e.g., after login).
    • Handles session regeneration on login.

    Example route:

    Route::post('/login', [AuthenticatedSessionController::class, 'store'])
         ->middleware('throttle:5,1'); // Rate limiting
    
  • Password Confirmation: Use Confirmable trait or ConfirmPasswordController for password confirmation prompts:

    Route::post('/user/confirm-password', [ConfirmPasswordController::class, 'store']);
    

2. Registration

  • User Creation: Extend CreateNewUser to customize registration logic:

    use Laravel\Fortify\Actions\CreateNewUser;
    
    class CustomCreateNewUser extends CreateNewUser
    {
        public function create(array $data)
        {
            return User::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'password' => Hash::make($data['password']),
                // Custom fields
            ]);
        }
    }
    

    Register it in FortifyServiceProvider:

    Fortify::createUsersUsing(CustomCreateNewUser::class);
    
  • Email Verification: Use VerifyEmailController and EnsureEmailIsVerified middleware:

    Route::get('/email/verify', [VerifyEmailController::class, 'show'])
         ->middleware('auth')
         ->name('verification.notice');
    
    Route::post('/email/verify', [VerifyEmailController::class, 'store'])
         ->middleware(['auth', 'signed', 'throttle:6,1']);
    

3. Password Reset

  • Reset Flow: Use ResetPasswordController for email-based resets:
    Route::post('/forgot-password', [ForgotPasswordController::class, 'store']);
    Route::post('/reset-password', [NewPasswordController::class, 'store']);
    
    Customize the ForgotPassword action to send emails:
    use Laravel\Fortify\Actions\ForgotPassword;
    
    class CustomForgotPassword extends ForgotPassword
    {
        public function sendResetLinkRequest()
        {
            $this->user->sendPasswordResetNotification($this->token);
        }
    }
    

4. Two-Factor Authentication (2FA)

  • Enable 2FA: Use EnableTwoFactorAuthentication and TwoFactorAuthenticatedSessionController:

    Route::post('/user/two-factor-authentication', [EnableTwoFactorAuthentication::class])
         ->middleware('auth');
    

    Add 2FA recovery codes:

    Route::post('/user/two-factor-recovery-codes', [RecoveryCodes::class])
         ->middleware('auth');
    
  • Session Handling: Use InteractsWithTwoFactorState trait to manage 2FA state across requests:

    use Laravel\Fortify\Features\TwoFactorAuthentication\InteractsWithTwoFactorState;
    
    class CustomController
    {
        use InteractsWithTwoFactorState;
    }
    

5. Passkeys (Modern Authentication)

  • Setup: Enable passkeys via FortifyServiceProvider:
    Fortify::enablePasskeys();
    
    Use PasskeyLoginController and PasskeyRegistrationController:
    Route::post('/passkey/register', [PasskeyRegistrationController::class, 'store']);
    Route::post('/passkey/login', [PasskeyLoginController::class, 'store']);
    

Integration Tips

1. Customizing Validation

Override validation rules in AuthenticatedSessionRequest, CreateNewUserRequest, etc.:

use Illuminate\Validation\Rules;

public function rules()
{
    return [
        'email' => ['required', 'string', 'email', 'max:255'],
        'password' => ['required', 'string', Rules\Password::min(8)],
    ];
}

2. Middleware Integration

Use Fortify’s built-in middleware:

  • EnsureEmailIsVerified: Redirect unverified users.
  • RedirectIfAuthenticated: Protect routes during registration/login.
  • TwoFactorAuthenticatable: Verify 2FA status.

Example:

Route::get('/dashboard', function () {
    // ...
})->middleware(['auth', 'verified', 'two-factor']);

3. Event Listeners

Listen to Fortify events (e.g., Registered, PasswordReset) in EventServiceProvider:

protected $listen = [
    \Laravel\Fortify\Events\Registered::class => [
        \App\Listeners\LogRegisteredUser::class,
    ],
];

4. Testing

Use Fortify facade to test authentication:

use Laravel\Fortify\Fortify;

public function test_login()
{
    $user = User::factory()->create();
    $response = $this->post('/login', [
        'email' => $user->email,
        'password' => 'password',
    ]);

    $this->assertAuthenticated();
}

5. API Authentication (Sanctum/Passport)

For SPAs, configure Sanctum in FortifyServiceProvider:

Fortify::createUsersUsing()->sanctum();

Use Sanctum middleware for API routes:

Route::middleware(['auth:sanctum', 'verified'])->get('/user', function () {
    return response()->json(['user' => auth()->user()]);
});

Gotchas and Tips

Pitfalls

  1. Session Regeneration:

    • Fortify regenerates sessions on login by default. Disable with:
      Fortify::regenerateSessionsOnLogin(false);
      
    • Issue: Session fixation attacks if disabled improperly.
  2. 2FA State Management:

    • The InteractsWithTwoFactorState trait must be used consistently across requests to avoid state mismatches.
    • Fix: Ensure all controllers handling 2FA include the trait.
  3. Password Reset Tokens:

    • Tokens expire after 60 minutes by default. Customize in ForgotPassword:
      public function createToken()
      {
          return Str::random(64);
      }
      
    • Gotcha: Case-sensitive password resets (fixed in v1.24.0).
  4. Passkey Compatibility:

    • Passkeys require modern browsers (Chrome 115+, Edge 115+, Safari 16.4+).
    • Fallback: Provide traditional email/password options.
  5. Middleware Conflicts:

    • RedirectIfAuthenticated may conflict with custom middleware. Use unless:
      Route::get('/login', function () {})->middleware('guest');
      
  6. Email Verification:

    • Verification links expire after 60 minutes. Customize in VerifyEmail:
      public function createToken()
      {
          return Str::random(64);
      }
      
    • Tip: Use signed middleware to validate tokens.
  7. Rate Limiting:

    • Fortify applies throttling to login/registration by default (5 attempts per minute).
    • Customize: Override in RouteServiceProvider:
      Route::fallback(function () {
          return response()->json(['message' => 'Not Found'], 4
      
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai