HTTPS für die lokale Entwicklung verwenden

Maud Nalpas
Maud Nalpas

In den meisten Fällen verhält sich http://localhost zu Entwicklungszwecken wie HTTPS. Es gibt jedoch einige Sonderfälle, z. B. benutzerdefinierte Hostnamen oder die Verwendung sicherer Cookies in verschiedenen Browsern, bei denen Sie Ihre Entwicklungswebsite explizit so einrichten müssen, dass sie sich wie HTTPS verhält, um die Funktionsweise Ihrer Website in der Produktion korrekt darzustellen. Wenn Ihre Produktionswebsite nicht HTTPS verwendet, sollten Sie sie so schnell wie möglich auf HTTPS umstellen.

Auf dieser Seite wird beschrieben, wie Sie Ihre Website lokal mit HTTPS ausführen.

Eine kurze Anleitung finden Sie in der mkcert-Kurzanleitung.**

Website lokal mit HTTPS mit mkcert ausführen (empfohlen)

Wenn Sie HTTPS mit Ihrer lokalen Entwicklungswebsite verwenden und auf https://localhost oder https://mysite.example (benutzerdefinierter Hostname) zugreifen möchten, benötigen Sie ein TLS-Zertifikat, das von einer Entität signiert wurde, der Ihr Gerät und Browser vertrauen. Diese Entität wird als vertrauenswürdige Zertifizierungsstelle (CA) bezeichnet. Der Browser prüft, ob das Zertifikat Ihres Entwicklungsservers von einer vertrauenswürdigen Zertifizierungsstelle signiert ist, bevor eine HTTPS-Verbindung hergestellt wird.

Wir empfehlen die Verwendung von mkcert, einer plattformübergreifenden Zertifizierungsstelle, zum Erstellen und Signieren Ihres Zertifikats. Weitere hilfreiche Optionen finden Sie unter Website lokal mit HTTPS ausführen: Weitere Optionen.

Viele Betriebssysteme enthalten Bibliotheken zum Erstellen von Zertifikaten, z. B. openssl. Sie sind jedoch komplexer und weniger zuverlässig als mkcert und nicht unbedingt plattformübergreifend, was sie für größere Entwicklerteams weniger zugänglich macht.

Einrichtung

  1. Installieren Sie mkcert (nur einmal).

    Folgen Sie der Anleitung zur Installation von mkcert auf Ihrem Betriebssystem. Beispiel für macOS:

    brew install mkcert
    brew install nss # if you use Firefox
    
  2. Fügen Sie mkcert Ihren lokalen Stamm-CAs hinzu.

    Führen Sie im Terminal den folgenden Befehl aus:

    mkcert -install
    

    Dadurch wird eine lokale Zertifizierungsstelle generiert. Die von mkcert generierte lokale Zertifizierungsstelle ist nur lokal auf Ihrem Gerät vertrauenswürdig.

  3. Generieren Sie ein Zertifikat für Ihre Website, das von mkcert signiert ist.

    Rufen Sie in Ihrem Terminal das Stammverzeichnis Ihrer Website oder das Verzeichnis auf, in dem Sie das Zertifikat speichern möchten.

    Führen Sie dann diesen Befehl aus:

    mkcert localhost
    

    Wenn Sie einen benutzerdefinierten Hostnamen wie mysite.example verwenden, führen Sie Folgendes aus:

    mkcert mysite.example
    

    Mit diesem Befehl werden zwei Dinge ausgeführt:

    • Generiert ein Zertifikat für den angegebenen Hostnamen.
    • Lassen Sie mkcert das Zertifikat signieren.

    Ihr Zertifikat ist jetzt fertig und wurde von einer Zertifizierungsstelle signiert, die von Ihrem Browser lokal als vertrauenswürdig eingestuft wird.

  4. Konfigurieren Sie Ihren Server so, dass er HTTPS mit dem gerade erstellten TLS-Zertifikat verwendet.

    Die Details dazu hängen von deinem Server ab. Hier einige Beispiele:

    👩🏻‍💻 Mit Knoten:

    server.js (ersetzt {PATH/TO/CERTIFICATE...} und {PORT}):

    const https = require('https');
    const fs = require('fs');
    const options = {
      key: fs.readFileSync('{PATH/TO/CERTIFICATE-KEY-FILENAME}.pem'),
      cert: fs.readFileSync('{PATH/TO/CERTIFICATE-FILENAME}.pem'),
    };
    https
      .createServer(options, function (req, res) {
        // server code
      })
      .listen({PORT});
    

    👩🏻‍💻 Mit http-server:

    Starten Sie den Server so (ersetzen Sie {PATH/TO/CERTIFICATE...}):

    http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
    

    -S führt Ihren Server mit HTTPS aus, während -C das Zertifikat und -K den Schlüssel festlegt.

    👩🏻‍💻 Mit einem React-Entwicklungsserver:

    Bearbeiten Sie package.json so und ersetzen Sie {PATH/TO/CERTIFICATE...}:

    "scripts": {
    "start": "HTTPS=true SSL_CRT_FILE={PATH/TO/CERTIFICATE-FILENAME}.pem SSL_KEY_FILE={PATH/TO/CERTIFICATE-KEY-FILENAME}.pem react-scripts start"
    

    Wenn Sie beispielsweise ein Zertifikat für localhost im Stammverzeichnis Ihrer Website erstellt haben:

    |-- my-react-app
        |-- package.json
        |-- localhost.pem
        |-- localhost-key.pem
        |--...
    

    Das start-Script sollte dann so aussehen:

    "scripts": {
        "start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"
    

    👩🏻‍💻 Weitere Beispiele:

  5. Öffnen Sie https://localhost oder https://mysite.example in Ihrem Browser, um zu prüfen, ob Ihre Website lokal mit HTTPS ausgeführt wird. Sie sehen keine Browserwarnungen, da Ihr Browser mkcert als lokale Zertifizierungsstelle vertraut.

Kurzreferenz für mkcert

So führen Sie Ihre lokale Entwicklungswebsite mit HTTPS aus:

  1. Richten Sie mkcert ein.

    Installieren Sie mkcert, falls noch nicht geschehen, z. B. unter macOS:

    brew install mkcert

    Eine Anleitung für Windows und Linux finden Sie unter install mkcert.

    Erstellen Sie dann eine lokale Zertifizierungsstelle:

    mkcert -install
  2. Erstellen Sie ein vertrauenswürdiges Zertifikat.

    mkcert {YOUR HOSTNAME e.g. localhost or mysite.example}

    Dadurch wird ein gültiges Zertifikat erstellt, das von mkcert automatisch signiert wird.

  3. Konfigurieren Sie Ihren Entwicklungsserver für die Verwendung von HTTPS und dem Zertifikat, das Sie in Schritt 2 erstellt haben.

Sie können jetzt ohne Warnungen in Ihrem Browser auf https://{YOUR HOSTNAME} zugreifen

</div>

Website lokal mit HTTPS ausführen: Weitere Optionen

Es gibt noch weitere Möglichkeiten, Ihr Zertifikat einzurichten. Diese sind in der Regel komplizierter oder riskanter als die Verwendung von mkcert.

Selbst signiertes Zertifikat

Sie können auch keine lokale Zertifizierungsstelle wie mkcert verwenden und stattdessen Ihr Zertifikat selbst signieren. Dieser Ansatz birgt einige Stolperfallen:

  • Da Sie von Browsern nicht als Zertifizierungsstelle vertraut werden, werden Warnungen angezeigt, die Sie manuell umgehen müssen. In Chrome können Sie das Flag #allow-insecure-localhost verwenden, um diese Warnung auf localhost automatisch zu umgehen.
  • Das ist unsicher, wenn Sie in einem unsicheren Netzwerk arbeiten.
  • Es ist nicht unbedingt einfacher oder schneller als die Verwendung einer lokalen Zertifizierungsstelle wie mkcert.
  • Selbst signierte Zertifikate verhalten sich nicht genau wie vertrauenswürdige Zertifikate.
  • Wenn Sie diese Methode nicht in einem Browserkontext verwenden, müssen Sie die Zertifikatsüberprüfung für Ihren Server deaktivieren. Wenn Sie vergessen, die Funktion in der Produktion wieder zu aktivieren, kann das zu Sicherheitsproblemen führen.
Screenshots der Warnungen, die in Browsern angezeigt werden, wenn ein selbst signiertes Zertifikat verwendet wird.
Die Warnungen, die von Browsern angezeigt werden, wenn ein selbst signiertes Zertifikat verwendet wird.

Wenn Sie kein Zertifikat angeben, wird in den HTTPS-Optionen des React- und Vue-Entwicklungsservers ein selbst signiertes Zertifikat erstellt. Das geht zwar schnell, aber es sind dieselben Browserwarnungen und anderen Fallstricke von selbst signierten Zertifikaten zu beachten. Glücklicherweise können Sie die integrierte HTTPS-Option von Frontend-Frameworks verwenden und ein lokal vertrauenswürdiges Zertifikat angeben, das mit mkcert oder einem ähnlichen Tool erstellt wurde. Weitere Informationen finden Sie im Beispiel mkcert mit React.

Wenn Sie Ihre lokal ausgeführte Website in Ihrem Browser über HTTPS öffnen, prüft der Browser das Zertifikat Ihres lokalen Entwicklungsservers. Wenn festgestellt wird, dass Sie das Zertifikat selbst signiert haben, wird geprüft, ob Sie als vertrauenswürdige Zertifizierungsstelle registriert sind. Da Sie dies nicht sind, kann Ihr Browser dem Zertifikat nicht vertrauen und zeigt eine Warnung an, dass Ihre Verbindung nicht sicher ist. Die HTTPS-Verbindung wird trotzdem hergestellt, wenn Sie fortfahren. Dies geschieht jedoch auf eigenes Risiko.

Warum vertrauen Browser selbst signierten Zertifikaten nicht: Ein Diagramm
Warum Browser selbst signierten Zertifikaten nicht vertrauen

Zertifikat, das von einer regulären Zertifizierungsstelle signiert wurde

Sie können auch ein von einer offiziellen Zertifizierungsstelle signiertes Zertifikat verwenden. Dies hat folgende Nachteile:

  • Die Einrichtung ist aufwendiger als bei einer lokalen Zertifizierungsstelle wie mkcert.
  • Sie müssen einen gültigen Domainnamen verwenden, den Sie verwalten. Das bedeutet, dass Sie offizielle Zertifizierungsstellen für Folgendes nicht verwenden können:

Reverse-Proxy

Eine weitere Möglichkeit, über HTTPS auf eine lokal ausgeführte Website zuzugreifen, ist die Verwendung eines Reverse-Proxys wie ngrok. Das birgt folgende Risiken:

  • Jeder, mit dem Sie die Reverse-Proxy-URL teilen, kann auf Ihre lokale Entwicklungswebsite zugreifen. Das kann hilfreich sein, um Ihr Projekt Kunden zu präsentieren, aber auch dazu führen, dass Unbefugte vertrauliche Informationen weitergeben.
  • Einige Reverse-Proxy-Dienste berechnen die Nutzung. Daher kann der Preis ein Faktor bei der Auswahl des Dienstes sein.
  • Neue Sicherheitsmaßnahmen in Browsern können sich auf die Funktionsweise dieser Tools auswirken.

Wenn Sie in Chrome einen benutzerdefinierten Hostnamen wie mysite.example verwenden, können Sie mit einem Flag festlegen, dass der Browser mysite.example als sicher betrachten soll. Vermeiden Sie dies aus folgenden Gründen:

  • Sie müssen sich zu 100% sicher sein, dass mysite.example immer in eine lokale Adresse aufgelöst wird. Andernfalls besteht das Risiko, dass Produktionsanmeldedaten preisgegeben werden.
  • Dieses Flag funktioniert nur in Chrome. Sie können also nicht plattformübergreifend debuggen.

Vielen Dank für die Beiträge und das Feedback aller Prüfer und Mitwirkenden, insbesondere von Ryan Sleevi, Filippo Valsorda, Milica Mihajlija und Rowan Merewood. 🙌

Hintergrund des Hero-Images von @anandu auf Unsplash, bearbeitet.