> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Passwort zurücksetzen

> Wie Sie das Zurücksetzen von Passwörtern in Laravel implementieren.

## Einführung

Das Zurücksetzen von Passwörtern gehört zu den unverzichtbaren Authentifizierungs-Flows einer Webanwendung. Nutzen Sie ein Starter-Kit, wird diese Funktion automatisch aufgebaut. In reinen API-Projekten oder wenn Sie ein eigenes UI aufbauen, ist eine manuelle Umsetzung nötig.

**Wann eine manuelle Umsetzung nötig ist:**

* Reines API-Backend (Frontend ist SPA oder Mobile App)
* Sie bauen die Auth-UI selbst, ohne Starter-Kit
* Sie möchten E-Mail-Benachrichtigungen oder Reset-URLs vollständig anpassen

<Info>
  Wenn Sie das Projekt mit einem Starter-Kit erstellt haben (`laravel new`), ist die Passwort-Reset-Funktion bereits implementiert. Diese Seite beschreibt die Umsetzung ohne Starter-Kit.
</Info>

Der gesamte Ablauf sieht so aus:

```mermaid theme={null}
flowchart TD
    A["Benutzer"] --> B["E-Mail-Adresse eingeben<br>GET /forgot-password"]
    B --> C["Reset-Link senden<br>POST /forgot-password"]
    C --> D["E-Mail empfangen<br>URL mit Token"]
    D --> E["Reset-Formular anzeigen<br>GET /reset-password/{token}"]
    E --> F["Passwort ändern<br>POST /reset-password"]
    F --> G["Weiterleitung zur<br>Login-Seite"]
```

## Konfiguration

Die Einstellungen für das Zurücksetzen von Passwörtern werden in `config/auth.php` unter dem Schlüssel `passwords` verwaltet.

```php theme={null}
// config/auth.php

'passwords' => [
    'users' => [
        'driver' => 'database',
        'provider' => 'users',
        'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
        'expire' => 60,
        'throttle' => 60,
    ],
],
```

* `driver` — Speicherart (`database` oder `cache`)
* `expire` — Gültigkeit des Tokens in Minuten. Standard: 60 Minuten
* `throttle` — Wartezeit bis zum nächsten Sendeversuch (in Sekunden)

## Treiber

### `database`-Treiber

Der Standardtreiber. Die Reset-Tokens werden in der Datenbanktabelle `password_reset_tokens` gespeichert. Diese Tabelle ist in der Standardmigration von Laravel (`0001_01_01_000000_create_users_table.php`) enthalten.

```php theme={null}
'passwords' => [
    'users' => [
        'driver' => 'database',
        'provider' => 'users',
        'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
        'expire' => 60,
        'throttle' => 60,
    ],
],
```

### `cache`-Treiber

<Tip>
  Diese Option ist ab Laravel 11 verfügbar. Da keine Datenbanktabelle nötig ist, können Sie das Zurücksetzen von Passwörtern mit einem schlanken Setup implementieren.
</Tip>

Der `cache`-Treiber speichert Tokens in einem Cache-Store. Die Migration für `password_reset_tokens` entfällt. Tokens werden unter dem Schlüssel „E-Mail-Adresse des Benutzers“ abgelegt – nutzen Sie daher an anderer Stelle in der App nicht dieselbe E-Mail-Adresse als Cache-Schlüssel.

```php theme={null}
'passwords' => [
    'users' => [
        'driver' => 'cache',
        'provider' => 'users',
        'store' => 'passwords', // optional: dedizierter Cache-Store
        'expire' => 60,
        'throttle' => 60,
    ],
],
```

Geben Sie im Schlüssel `store` einen dedizierten Cache-Store an, verhindern Sie, dass Ihre Reset-Daten durch `php artisan cache:clear` gelöscht werden. Der Wert muss einem in `config/cache.php` konfigurierten Store-Namen entsprechen.

## Modell vorbereiten

Damit das Zurücksetzen von Passwörtern funktioniert, braucht das Modell `App\Models\User` zwei Traits.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable, CanResetPassword;

    // ...
}
```

* `Notifiable` — nötig, um E-Mail-Benachrichtigungen zu versenden
* `CanResetPassword` — stellt Methoden zum Erzeugen und Prüfen von Reset-Tokens bereit

<Info>
  Das Standardmodell `User` von Laravel enthält diese Traits bereits. Bei einer Neuinstallation müssen Sie nichts hinzufügen.
</Info>

## Routen umsetzen

Das Zurücksetzen von Passwörtern benötigt vier Routen.

### 1. Formular zum Anfordern eines Reset-Links

Zeigt ein Formular an, in dem der Benutzer die E-Mail-Adresse eingibt.

```php theme={null}
// routes/web.php

Route::get('/forgot-password', function () {
    return view('auth.forgot-password');
})->middleware('guest')->name('password.request');
```

Zugehörige Blade-View:

```blade theme={null}
{{-- resources/views/auth/forgot-password.blade.php --}}

<form method="POST" action="/forgot-password">
    @csrf

    <div>
        <label for="email">E-Mail-Adresse</label>
        <input id="email" type="email" name="email" value="{{ old('email') }}" required autofocus>
        @error('email')
            <span>{{ $message }}</span>
        @enderror
    </div>

    @if (session('status'))
        <div>{{ session('status') }}</div>
    @endif

    <button type="submit">Reset-Link senden</button>
</form>
```

### 2. Versand des Reset-Links verarbeiten

Nimmt das Formular entgegen und versendet mit `Password::sendResetLink()` die Reset-E-Mail.

```php theme={null}
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;

Route::post('/forgot-password', function (Request $request) {
    $request->validate(['email' => 'required|email']);

    $status = Password::sendResetLink(
        $request->only('email')
    );

    return $status === Password::ResetLinkSent
        ? back()->with(['status' => __($status)])
        : back()->withErrors(['email' => __($status)]);
})->middleware('guest')->name('password.email');
```

`Password::sendResetLink()` gibt einen Status-String zurück.

| Status-Konstante            | Beschreibung                                     |
| --------------------------- | ------------------------------------------------ |
| `Password::ResetLinkSent`   | Reset-Link wurde gesendet                        |
| `Password::INVALID_USER`    | Kein Benutzer mit dieser E-Mail-Adresse gefunden |
| `Password::RESET_THROTTLED` | Der Versand ist begrenzt (Throttling)            |

### 3. Passwort-Reset-Formular

Zeigt dem Benutzer, der den Link in der E-Mail geklickt hat, ein Formular zur Eingabe eines neuen Passworts an.

```php theme={null}
Route::get('/reset-password/{token}', function (string $token) {
    return view('auth.reset-password', ['token' => $token]);
})->middleware('guest')->name('password.reset');
```

Zugehörige Blade-View:

```blade theme={null}
{{-- resources/views/auth/reset-password.blade.php --}}

<form method="POST" action="/reset-password">
    @csrf

    <input type="hidden" name="token" value="{{ $token }}">

    <div>
        <label for="email">E-Mail-Adresse</label>
        <input id="email" type="email" name="email" value="{{ old('email') }}" required autofocus>
        @error('email')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="password">Neues Passwort</label>
        <input id="password" type="password" name="password" required>
        @error('password')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="password_confirmation">Passwort bestätigen</label>
        <input id="password_confirmation" type="password" name="password_confirmation" required>
    </div>

    <button type="submit">Passwort zurücksetzen</button>
</form>
```

### 4. Passwort-Reset ausführen

Nimmt das Formular entgegen und aktualisiert mit `Password::reset()` das Passwort.

```php theme={null}
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;

Route::post('/reset-password', function (Request $request) {
    $request->validate([
        'token' => 'required',
        'email' => 'required|email',
        'password' => 'required|min:8|confirmed',
    ]);

    $status = Password::reset(
        $request->only('email', 'password', 'password_confirmation', 'token'),
        function (User $user, string $password) {
            $user->forceFill([
                'password' => Hash::make($password),
            ])->setRememberToken(Str::random(60));

            $user->save();

            event(new PasswordReset($user));
        }
    );

    return $status === Password::PasswordReset
        ? redirect()->route('login')->with('status', __($status))
        : back()->withErrors(['email' => [__($status)]]);
})->middleware('guest')->name('password.update');
```

Status-Konstanten von `Password::reset()`:

| Status-Konstante          | Beschreibung                                     |
| ------------------------- | ------------------------------------------------ |
| `Password::PasswordReset` | Passwort-Reset erfolgreich                       |
| `Password::INVALID_TOKEN` | Token ungültig oder abgelaufen                   |
| `Password::INVALID_USER`  | Kein Benutzer mit dieser E-Mail-Adresse gefunden |

## Token-Gültigkeit

Über die Option `expire` in `config/auth.php` legen Sie die Gültigkeit des Tokens in Minuten fest. Standard: 60 Minuten.

```php theme={null}
'passwords' => [
    'users' => [
        'driver' => 'database',
        'expire' => 60, // Läuft nach 60 Minuten ab
        'throttle' => 60,
    ],
],
```

Beim `database`-Treiber bleiben abgelaufene Tokens in der Datenbank stehen. Mit folgendem Artisan-Befehl räumen Sie sie regelmäßig auf.

```shell theme={null}
php artisan auth:clear-resets
```

Am besten automatisieren Sie das über den Scheduler.

```php theme={null}
use Illuminate\Support\Facades\Schedule;

Schedule::command('auth:clear-resets')->everyFifteenMinutes();
```

## Anpassungen

### Eigene Benachrichtigung

Um die Reset-E-Mail anzupassen, überschreiben Sie im `User`-Modell die Methode `sendPasswordResetNotification`.

```php theme={null}
use App\Notifications\ResetPasswordNotification;

class User extends Authenticatable
{
    use Notifiable, CanResetPassword;

    /**
     * Passwort-Reset-Benachrichtigung senden
     */
    public function sendPasswordResetNotification($token): void
    {
        $url = 'https://example.com/reset-password?token='.$token;

        $this->notify(new ResetPasswordNotification($url));
    }
}
```

### Reset-Link-URL anpassen

Mit `ResetPassword::createUrlUsing()` in der Methode `boot` des `AppServiceProvider` ändern Sie die URL des Reset-Links. Nützlich, wenn Sie – etwa bei einem SPA – auf ein anderes Frontend-Origin weiterleiten möchten.

```php theme={null}
use App\Models\User;
use Illuminate\Auth\Notifications\ResetPassword;

public function boot(): void
{
    ResetPassword::createUrlUsing(function (User $user, string $token) {
        return 'https://example.com/reset-password?token='.$token;
    });
}
```

### Trusted Hosts konfigurieren

Die Reset-URL wird aus dem `Host`-Header des HTTP-Requests aufgebaut. Um Requests von unerlaubten Hosts zu unterbinden, empfehlen wir die Konfiguration von Trusted Hosts in `bootstrap/app.php`.

```php theme={null}
->withMiddleware(function (Middleware $middleware) {
    $middleware->trustHosts(at: ['example.com']);
})
```

<Warning>
  Wenn Sie das Zurücksetzen von Passwörtern anbieten, prüfen Sie unbedingt Ihre Trusted-Hosts-Konfiguration. Eine unzureichende Konfiguration birgt das Risiko einer Host-Header-Injection.
</Warning>

## Zusammenfassung

| Ziel                             | Vorgehen                                       |
| -------------------------------- | ---------------------------------------------- |
| Reset-Link versenden             | `Password::sendResetLink(['email' => $email])` |
| Passwort zurücksetzen            | `Password::reset($credentials, $callback)`     |
| Reset ohne Datenbanktabelle      | `cache`-Treiber konfigurieren                  |
| Abgelaufene Tokens entfernen     | `php artisan auth:clear-resets`                |
| E-Mail-Benachrichtigung anpassen | `sendPasswordResetNotification` überschreiben  |
| Reset-URL anpassen               | `ResetPassword::createUrlUsing()`              |

## Nächste Schritte

<Columns cols={2}>
  <Card title="Einführung in Authentifizierung" icon="lock" href="/de/authentication">
    Verstehen Sie das gesamte Authentifizierungssystem von Laravel.
  </Card>

  <Card title="Notifications" icon="bell" href="/de/notifications">
    Erfahren Sie mehr zum Anpassen von E-Mail-Benachrichtigungen.
  </Card>
</Columns>


## Related topics

- [Migrations-Guide von laravel/ui zu Fortify](/de/blog/ui-to-fortify.md)
- [Hashing](/de/hashing.md)
- [Eloquent Bootable Traits](/de/advanced/eloquent-bootable-traits.md)
- [Datenbanktests](/de/database-testing.md)
- [Macroable-Trait](/de/advanced/macroable.md)
