Laravel & Statamic ohne Cookies einsetzen

Jeder kennt sie, niemand mag sie: Cookie-Banner. Pflicht sind diese nur dann, wenn technisch nicht notwendige Cookies eingesetzt werden sollen. Aber bei der Notwendigkeit scheiden sich die Geister. Am sichersten fährt man natürlich ganz ohne Cookies. Wie man die Cookies bei Laravel abschaltet und worauf man dabei achten muss, erkläre ich Euch in diesem Artikel.

Welche Cookies verwendet Laravel überhaupt?

Wenn Ihr eine frische Laravel-Applikation aufsetzt, dann werden standard-mäßig zwei verschiedene Cookies verwendet. Zum einen ist da der Session-Cookie. Dieser speichert zum Beispiel Formulareingaben, Fehlermeldungen und alles was Ihr sonst so in der Benutzer-Session speichern wollt. Der zweite Cookie ist der XSRF-Token. Dieser wird in Formularen verwendet, um (wie der Name schon sagt) Cross Site Request Forgery zu verhindern.

Sind die Laravel-Cookies technisch notwendig?

Hier möchte ich einmal vorweg schicken, dass ich kein Anwalt bin. Das ist keine rechtliche Beratung. Ich kann hier nur wiedergeben, was ich anderswo gelesen und gehört habe. Im Zweifel solltet Ihr also bitte einen fachkundigen Anwalt kontaktieren.

Aber zurück zum eigentlichen Thema. Zunächst einmal könnte man die Frage hier pauschal bejahen. Beide Cookies dienen immerhin dazu, dass bestimmte Bereiche Eurer Applikation funktionieren. Aber hier liegt auch schon der Hund begraben. Bestimmte Bereiche.

Einige Behörden sind der Auffassung, dass nur weil Ihr zum Beispiel irgendwo auf der Seite ein Formular habt, ihr nicht einfach pauschal einen Session-Cookie für Formulareingaben registrieren dürft. Entscheidend könnte sein, ob der Besucher das Formular auch benutzen will. Anders gelagert ist der Fall noch einmal, wenn Ihr überhaupt kein Formular auf Eurer Seite anbietet. Warum dann einen XSRF-Token speichern? Wer könnte dann von technischer Notwendigkeit sprechen?

Jaaa, werdet Ihr sagen. Aber ich brauche den ja für das Login-Formular. Das nutzen meine Redakteure. Naja gut, aber eben nicht alle regulären Benutzer der Seite. Es ist für diese also nicht notwendig. Man sieht, man kommt da schnell in ambivalente Situationen. Warum also nicht die Cookies gleich ganz abschalten?

Kann ich die Cookies einfach ganz deaktivieren?

Das kommt ganz darauf an. Wenn Du keine Cookies brauchst, also zum Beispiel keinen Login verwendest und nirgendwo auf der Seite Formulare im Einsatz sind, dann kannst Du die Cookies einfach abschalten. Cookies werden bei Laravel in Middlewares definiert. Du kannst also im Grunde genommen einfach diese Middlewares abschalten.

Alle Middlewares werden in der Kernel.php definiert. Die findest Du in der Regel hier: app/Http/Kernel.php. Dort musst Du folgende Middlewares auskommentieren:

  • App\Http\Middleware\VerifyCsrfToken

  • Illuminate\Session\Middleware\StartSession

Das wars auch schon. Im Anschluss musst Du einmal Deine Cookies löschen, sofern Du die Seite bereits besucht hast. Wenn Du Deine Seite nun erneut aufrufst, sollten keine Cookies mehr gesetzt werden.

Was wenn ich die Cookies nicht deaktivieren kann?

Wenn Du die Cookies generell brauchst, kannst Du sie natürlich einfach aktiviert lassen. Wenn Du sie allerdings nur in bestimmten Bereichen brauchst und auf Nummer sicher gehen möchtest, wird der Fall schon etwas komplizierter. Hier müssen wir in die beiden oben genannten Middlewares eingreifen.

Es gibt zwei Methoden in VerifyCsrfToken und StartSession, die wir uns zunutzen machen können. Fangen wir zunächst einmal bei VerifyCsrfToken an. Diese Klasse wird bereits von Laravel selbst innerhalb unserer Applikation erstellt und kann einfach angepasst werden.

Hier gibt es die geerbte Methode shouldAddXsrfTokenCookie(). Diese können wir in unserer eigenen Klasse überschreiben. Dort können wir dann zum Beispiel prüfen, ob der Benutzer einen bestimmten Pfad aufgerufen hat. Im Idealfall würde man hier natürlich eher einen regulären Ausdruck verwenden, aber zum Verständnis halte ich es an dieser Stelle simpel.

Das kann dann so aussehen:

class VerifyCsrfToken extends Middleware
{
    public function shouldAddXsrfTokenCookie(): bool
    {
        if (request()->path() === 'login') {
            // Let the parent class do its magic.
            return parent::shouldAddXsrfTokenCookie();
        }
        
        // We only want Cookies for the login path.
        return false;
    }
}

Nun müssen wir noch StartSession anpassen. Das gestaltet sich etwas aufwändiger, ist aber auch nicht allzu kompliziert. Zunächst müssen wir eine eigene Klasse StartSession erstellen. Von Haus aus verwendet Laravel nämlich einfach die Klasse aus einem Paket. Unsere Klasse StartSession erbt dann von der Original-Klasse. Du kannst die Klasse natürlich auch anders nennen.

Das sieht dann so aus:

namespace App\Http\Middleware;

class StartSession extends \Illuminate\Session\Middleware\StartSession
{

}

Anschließend müssen wir unsere Klasse noch in der Kernel.php registrieren. Wir ersetzen dort also Illuminate\Session\Middleware\StartSession mit App\Http\Middleware\StartSession. Schon können wir auch hier in die Middleware eingreifen. Hier können wir die geerbte Methode sessionIsPersistent() überschreiben und anpassen. Wir checken zu Demonstrationszwecken wieder einfach, ob der aufgerufene Pfad login ist.

class StartSession extends \Illuminate\Session\Middleware\StartSession
{
    protected function sessionIsPersistent(array $config = null): bool
    {
        if (request()->path() === 'login') {
            // Let the parent class do its magic.
            return parent::sessionIsPersistent($config);
        }

        // We only want Cookies for the login path.
        return false;
    }
}

Und das wars auch schon. Cookies werden nun nur noch für unseren Beispiel-Pfad gesetzt. Natürlich könnt Ihr dort gänzlich frei alles überprüfen, was Ihr wollt. Gängig ist zum Beispiel eine Allow List mit verschiedenen Pfaden zu definieren und diese dann zu überprüfen.

Und was muss ich bei Statamic beachten?

Bei Statamic funktioniert das Ganze eigentlich recht ähnlich. Ich habe das Problem hier zum Beispiel so gelöst, dass alle Formulare in einer eigenen Collection landen und alle Pfade der Pattern form/xyz folgen. Statamic selber sendet alle Formulare an einen Pfad !/form/xyz und verarbeitet die Eingaben dort. Zudem gibt es natürlich noch das Control Panel, wofür auch noch einmal Cookies benötigt werden. Die Route zum Control Panel lässt sich über die Konfiguration frei definieren.

Der Einfachheit halber habe ich das alles dann in einem Trait zusammen gefasst:

trait CookieAllowed
{
    private function isCookieAllowed(string $path): bool
    {
        $pattern = '/^(!\/forms\/|form|' . config('statamic.cp.route') . ')/i';
        if (!preg_match($pattern, $path, $matches)) {
            return false;
        }

        return true;
    }
}

Diesen Trait nutze ich dann in den beiden Middlewares. Also in VerifyCsrfToken:

class VerifyCsrfToken extends Middleware
{
    use CookieAllowed;

    public function shouldAddXsrfTokenCookie(): bool
    {
        if ($this->isCookieAllowed(request()->path())) {
            return parent::shouldAddXsrfTokenCookie();
        }

        return false;
    }
}

Und natürlich auch noch einmal in StartSession:

class StartSession extends \Illuminate\Session\Middleware\StartSession
{
    use CookieAllowed;

    protected function sessionIsPersistent(array $config = null): bool
    {
        if ($this->isCookieAllowed(request()->path())) {
            return parent::sessionIsPersistent($config);
        }

        return false;
    }
}

Cookies werden nun nur noch gesetzt, wenn es für Statamic unbedingt erforderlich ist. Auf ein Cookie-Banner könnt Ihr dann (meiner Meinung nach) problemlos verzichten.

Ich hoffe ich konnte eine wenig Licht ins Dunkel der Laravel-Cookies bringen. Solltet Ihr Fragen oder Anmerkungen haben, lasst es mich gerne in den Kommentaren wissen. Ansonsten könnt Ihr natürlich auch gerne das Kontaktformular nutzen. Ich verabschiede mich an dieser Stelle. Bis dahin, gehabt Euch wohl.

Noch keine Kommentare vorhanden.