TypeScript erweitert JavaScript um statische Typen; der Compiler prüft die Typen und erzeugt daraus normales JavaScript. Wer ankommende Daten als any deklariert, verschenkt diesen Schutz vollständig.
🌐 Externe Daten aus dem Netz sind zur Laufzeit nicht typisiert. JSON ist das verbreitete Datenformat von Web-APIs: Objekte mit Schlüssel-Wert-Paaren, Listen, Zeichenketten, Zahlen sowie true, false und null. Das Backend eines anderen Anbieters kann jederzeit ein Feld weglassen, null statt einer Zahl liefern oder ein Objekt statt einer Liste schicken. Der Typ im eigenen Code weiß davon nichts.
🧩 any schaltet den Typprüfungspfad ab, unknown erzwingt ihn. Der Typ any akzeptiert jede Operation, auch solche, die zur Laufzeit scheitern. Der Typ unknown ist die typsichere Variante: Der Wert darf darin landen, aber jede Operation erfordert vorher eine Typprüfung (Narrowing, das schrittweise Einengen des Typs), sonst kompiliert der Code nicht.
🔒 Erst prüfen, dann typisieren – Schritt für Schritt. JSON.parse liefert in TypeScript any, das Ergebnis einer fetch-Abfrage muss ebenfalls selbst geprüft werden. Bewährt hat sich: Das Ergebnis sofort unknown zuzuweisen. Dann mit typeof primitive Werte prüfen, mit Array.isArray Listen erkennen und einzelne Felder gegen erwartete Typen vergleichen. Erst danach den Wert einem echten Typ wie User zuweisen.
any heißt nicht „irgendein Typ“, sondern „keine Prüfung mehr“. unknown heißt nicht „unbekannt und ungeeignet“, sondern „unbekannt und kontrolliert“.
📌 unknown statt any · Typprüfung mit Narrowing · JSON.parse liefert any
📚 Webentwicklung von Grund auf · Tag 6 von 30
#typescript #webdev #javascript
Trotz unveränderter Konfiguration entstehen doppelte Ressourcen in der Cloud. Die alten Instanzen laufen weiter und verursachen weiterhin Kosten.
Terraform hält in einer State-Datei fest, welche echten Cloud-Ressourcen zu welchem Konfigurationseintrag gehören. Dieser State ist Terraforms Gedächtnis: Er speichert den Zustand, den Terraform beim letzten apply beobachtet hat. Bei jedem Lauf vergleicht Terraform den Soll-Zustand aus den .tf-Dateien, den Ist-Zustand aus dem State und die reale Cloud.
In der Konfiguration steht eine EC2-Instanz namens web-server. Nach dem apply liegt die Instanz-ID der erzeugten Cloud-Instanz im State. Genau diese ID erlaubt Terraform bei einer späteren Änderung, dieselbe Instanz zu aktualisieren statt eine neue zu bauen. Ohne State entsteht beim nächsten apply eine doppelte Instanz.
So prüft man es: Nach terraform apply die Ausgabe darauf prüfen, ob sie nur beabsichtigte Änderungen zeigt. Erscheinen Ressourcen als komplett neu, fehlt vermutlich die Zuordnung im State.
Der State ist kein Protokoll, sondern ein Abbuchungsregister: Er entscheidet, welche echte Ressource beim Abbau entfernt wird. Deshalb gehört er geschützt in ein Remote-Backend, ein zentraler Ablageort für den State, etwa ein S3-Bucket; dort verhindert State-Locking, dass zwei Läufe gleichzeitig denselben State überschreiben. Weil der State Klartext wie Passwörter enthalten kann, hat er nichts in Git verloren.
Ein verlorener State lässt sich über Import-Werkzeuge teilweise zurückholen. Einfacher ist es, ihn nie zu verlieren.
State heißt nicht Nebenprodukt, sondern Gedächtnis ohne Rückversicherung.
📌 State-Datei · Remote-Backend · State-Locking
📚 Cloud von Grund auf · Tag 6 von 30
#Terraform #iac #devops
Mehrere SQL-Befehle können zu einer unteilbaren Einheit gebündelt werden. Das passiert überall dort, wo mehrere Schritte zusammengehören, etwa bei jeder Überweisung.
Zuerst beginnt die Transaktion mit BEGIN (dem Startbefehl der Einheit). Eine Überweisung von Konto A auf Konto B besteht aus zwei Befehlen. Der erste UPDATE-Befehl verringert den Kontostand von A.
Dann erhöht ein zweites UPDATE den Kontostand von B. SQL ist die Abfragesprache relationaler Datenbanken wie PostgreSQL; UPDATE ändert darin bestehende Zeilen. Beide Befehle gehören zwingend in dieselbe Transaktion.
Danach entscheidet der Abschluss. Läuft alles fehlerfrei, macht COMMIT alle Änderungen dauerhaft sichtbar. Schlägt ein Schritt fehl, etwa weil Konto B nicht existiert, verwirft ROLLBACK alles. Die Datenbank steht dann so da, als wäre nichts geschehen.
Zuletzt ein Blick auf den Einsteigerirrtum: Viele setzen jeden SQL-Befehl einzeln ab und vertrauen darauf, dass die Datenbank die Zusammengehörigkeit von selbst erkennt. Das Gegenteil ist der Fall. Ohne BEGIN führt die Datenbank jeden Befehl sofort eigenständig aus; dieses Verhalten heißt Autocommit. Das Geld wäre dann schon von A abgebucht, ohne dass B je etwas erhielt.
Diese Alles-oder-nichts-Eigenschaft heißt Atomicität. Sie ist eine der vier Grundeigenschaften, die zuverlässige Datenbanksysteme garantieren.
Transaktion heißt nicht „mehrbefehliges Skript“, sondern unteilbare Einheit: erst COMMIT macht dauerhaft, ROLLBACK nimmt alles zurück.
📌 BEGIN · COMMIT · ROLLBACK
📚 Webentwicklung von Grund auf · Tag 5 von 30
#PostgreSQL #backend #webdev
Viele denken, Terraform finde die realen Ressourcen sowieso in der Cloud. Das klingt plausibel, denn Instanzen und Netzwerke sind sichtbar in der Konsole.
Tatsächlich vergleicht Terraform bei jedem Lauf drei Dinge: den Soll-Zustand aus den .tf-Dateien, den Ist-Zustand aus dem State und den realen Zustand in der Cloud. Der State ist Terraforms Gedächtnis; er speichert für jede Ressource, was beim letzten apply, dem Befehl, der Änderungen ausführt, existierte. Ohne ihn weiß Terraform nicht, welche echte Instanz zu welcher Konfigurationszeile gehört.
Der Irrtum entsteht, weil die Ressourcen nach dem Löschen der Datei weiterlaufen. Erst der nächste apply zeigt die Folge: Neue, doppelte Ressourcen entstehen.
In der Konfiguration steht eine EC2-Instanz namens web-server. Nach dem apply landet die Instanz-ID der erzeugten Cloud-Instanz im State. Genau diese ID erlaubt Terraform später, dieselbe Instanz zu aktualisieren, statt eine neue zu bauen.
Woran man es erkennt: terraform plan meldet plötzlich, dass Ressourcen neu erstellt werden sollen, obwohl die Konfiguration unverändert ist. Nach dem darauffolgenden apply zeigt die Konsole dann doppelte Instanzen.
In Teams gehört der State in ein Remote-Backend wie S3, also eine zentrale Ablage, auf die alle zugreifen; Locking über DynamoDB oder S3-Lock-Dateien verhindert gleichzeitige Änderungen. Der State kann Klartext-Passwörter enthalten und ist ein Geheimnis.
State heißt nicht nebensächliches Nebenprodukt, sondern das Gedächtnis, das Konfiguration und reale Ressourcen verbindet. Verlorener State bedeutet: Die Cloud bleibt bestehen, aber Terraform kann sie nicht mehr zuordnen.
📌 State-Datei · Remote-Backend · Locking
📚 Cloud von Grund auf · Tag 5 von 30
#Terraform #iac #aws
Das Register listet Begriffe alphabetisch, jeweils mit einer Seitenzahl daneben. Wer „Mutation“ sucht, blättert nicht, sondern springt direkt zur angegebenen Seite. Neu aufgenommene Begriffe müssen sich an der richtigen Stelle einreihen. Deshalb bleibt das Register sortiert, egal wie oft das Buch sich füllt.
Fachlich ist der Index eine sortierte Zusatzstruktur neben der Tabelle. Er speichert die Werte einer Spalte in sortierter Form, jeweils mit einem Verweis auf die zugehörige Zeile. Der Standard-Indextyp ist der B-Tree, der Gleichheit und Bereichsvergleiche sowie Sortierung unterstützt. Die Datenbank steigt darin wie im Lexikon von Verweis zu Verweis ab, statt alle Zeilen zu lesen.
Ohne Index führt die Datenbank bei einer Abfrage mit WHERE einen Sequential Scan aus: Sie prüft jede Zeile einzeln. In einer Bestelltabelle mit Millionen Zeilen gehört daher ein Index auf die Kundennummer, den Fremdschlüssel, der auf den Primärschlüssel verweist, der jede Zeile der Kundentabelle eindeutig identifiziert. Mit EXPLAIN zeigt PostgreSQL den Ausführungsplan der Abfrage, mit EXPLAIN ANALYZE wird sie zusätzlich ausgeführt und zeigt dann tatsächliche Zeiten und Zeilenzahlen.
Das Bild hat eine Grenze: Ein Buchregister wird einmal gesetzt, ein Index muss bei jedem Schreiben gepflegt werden. Jeder zusätzliche Index verlangsamt INSERT, UPDATE und DELETE und belegt Speicherplatz.
Ein Index heißt nicht „automatisch schneller“, sondern „schneller finden bei gezielten Fragen“. Er gehört auf Spalten, nach denen häufig gefiltert, sortiert oder verbunden wird, nicht auf jede Spalte.
📌 Sortierte Zusatzstruktur · B-Tree · Schreibkosten
📚 Webentwicklung von Grund auf · Tag 5 von 30
#PostgreSQL #backend #webdev
In der Tabelle bestellungen stehen Name und Adresse des Kunden in jeder Zeile kopiert. Nach einer Änderung stimmen manche Zeilen, andere nicht, und niemand weiß, welche Kopie die richtige ist.
In einer relationalen Datenbank wie PostgreSQL liegen Daten in Tabellen aus Zeilen und Spalten. Jede Zeile braucht einen Primärschlüssel, also eine Spalte, deren Wert genau einmal vorkommt, oft eine fortlaufende ID, die die Datenbank beim Einfügen vergibt. Ohne eindeutige Kennung wüsste die Datenbank bei zwei inhaltsgleichen Zeilen nicht, welche gemeint ist; ein UPDATE oder DELETE könnte die falsche Zeile treffen. Der Fremdschlüssel löst das Kopierproblem: Er speichert nicht die Daten selbst, sondern nur den Verweis auf den Primärschlüssel der anderen Tabelle.
In der Tabelle kunden bekommt jeder Kunde eine eigene ID. Die Tabelle bestellungen enthält statt Name und Adresse nur die Spalte kunden_id mit dem Wert 7. Ändert sich der Kundenname, wird er genau einmal in kunden geändert, und alle Bestellungen sehen automatisch den neuen Wert. Die Datenbank prüft dabei die Gültigkeit: Eine Bestellung mit einer kunden_id, die es gar nicht gibt, wird mit einem Fehler abgewiesen.
So prüft man es: Nachschauen, ob jede Tabelle einen Primärschlüssel hat und ob zusammengehörige Daten über Fremdschlüssel verbunden sind. Kopierte Kundendaten in jeder Bestellzeile sind ein Alarmzeichen.
Der Fehler heißt nicht schlampige Pflege, sondern fehlende Schlüssel. Wer eindeutig kennzeichnet und nur verweist, speichert jede Information genau einmal.
📌 Primärschlüssel · Fremdschlüssel · Verweis statt Kopie
📚 Webentwicklung von Grund auf · Tag 5 von 30
#PostgreSQL #backend #webdev
Beide sind Dateien mit Ressourcen drin, deshalb hält man sie für dasselbe. Doch sie beantworten verschiedene Fragen: den Soll-Zustand und den Ist-Stand.
Die Konfiguration ist der Bauplan: In Terraform-Dateien steht in deklarativer Sprache, was entstehen soll, etwa eine Security-Group, also eine Firewall-Regelgruppe in AWS. Sie beschreibt Eigenschaften, aber keine konkreten Cloud-Objekte. Ein Beispiel: eine Regel, die einen Port für HTTPS freigibt. Terraform liest sie bei jedem Lauf neu ein.
Der State ist das Gedächtnis von Terraform: eine Datei, die für jede Ressource der Konfiguration festhält, welche echte Ressource in der Cloud dazugehört, etwa über deren konkrete ID. Steht dort eine Security-Group mit einer ID, kennt Terraform genau dieses Objekt. Fehlt der State, kann Terraform bestehende Ressourcen nicht mehr verwalten.
Die Konfiguration ist der Wunsch, der State die Zuordnung zur Wirklichkeit. Beim Plan vergleicht Terraform drei Dinge – Konfiguration, State und reale Ressourcen – und leitet daraus die Änderungen ab.
Faustregel: Wer Änderungen plant, braucht zuerst einen aktuellen State, sonst sind Plan und Wirklichkeit auseinander. Deshalb liegt der State zentral in einem Remote-Backend wie S3, einem Speicher, den alle Beteiligten gemeinsam nutzen.
Vorsicht: Der State kann Passwörter im Klartext enthalten und ist wie ein Geheimnis zu schützen. Löschen ist keine Aufräumlösung, sondern verwirft nur das Gedächtnis und erzeugt Duplikate.
Der State ist nicht die Konfiguration, sondern das Gedächtnis, das beide verbindet. Ohne ihn weiß Terraform nicht, was es selbst angelegt hat.
📌 Konfiguration · State · Remote-Backend
📚 Cloud von Grund auf · Tag 5 von 30
#Terraform #iac #devops #CloudSecurity
Nur mit festen Spalten kann die Datenbank Daten prüfen, vergleichen und verbinden. Ohne dieses Gerüst wären Verweise zwischen Datensätzen blind.
🌐 Eine relationale Datenbank wie PostgreSQL legt Daten in Tabellen aus Zeilen und Spalten ab. Jede Zeile ist genau ein Datensatz, etwa ein Kunde mit Name und E-Mail-Adresse. Jede Spalte ist ein Feld dieses Datensatzes, mit einem festen Namen und Datentyp wie Text oder Zahl.
🧩 Ein Primärschlüssel identifiziert jede Zeile eindeutig, etwa über eine Spalte id. Ein Fremdschlüssel verweist auf den Primärschlüssel einer anderen Tabelle und verbindet zusammengehörige Daten. So hängt eine Tabelle bestellungen mit der Spalte kunde_id an kunden.id: Jede Bestellung gehört zu genau einem Kunden.
🔒 Die Spalten gelten für alle Zeilen und werden vorab festgelegt. Eine neue Zeile fügt Daten hinzu, nie eine neue Spalte – das Gerüst ist starr und dadurch verlässlich. Weil jedes Feld Namen und Typ hat, kann die Datenbank Eingaben prüfen, Werte vergleichen und Verbindungen sicher auflösen.
Das Ganze nennt man Datenbankschema: die Beschreibung aller Tabellen und Spalten, die vor den Daten entsteht. Tabellen sind dabei keine Tabellenkalkulation: Es gibt keine bedeutsame Zeilenreihenfolge, Verweise laufen immer über Schlüssel. Das Grundgerüst heißt nicht flexibel, sondern vorhersehbar – und genau das macht Ordnung erst möglich.
📌 Tabelle · Zeile und Spalte · Schlüssel
📚 Webentwicklung von Grund auf · Tag 5 von 30
#PostgreSQL #backend #webdev
Das Grundbuch verzeichnet jedes Grundstück mit Nummer, Besitzer und aktuellem Zustand. Will der Planer ein Haus umbauen, schlägt er erst nach: Ist das Grundstück bereits eingetragen? Ist der Zustand dort noch aktuell? Erst dann entscheidet er, ob gebaut, umgebaut oder abgerissen wird.
Bei Terraform heißt das Grundbuch State: eine Datei mit der Zuordnung zwischen dem Namen in der Konfiguration, also den Textdateien, die Infrastruktur beschreiben, und der realen Ressource in der Cloud. Bei jedem terraform plan oder terraform apply vergleicht Terraform drei Dinge: den gewünschten Zustand, den gespeicherten Ist-Zustand und die echte Cloud. Aus der Differenz ergibt sich, was erstellt, geändert oder gelöscht wird.
Konkret: In der Konfiguration steht eine EC2-Instanz (virtuelle Maschine bei AWS) mit dem Namen webserver. Im State liegt dazu die ID der realen Instanz, etwa i-abc123. Nur über diese Zuordnung findet Terraform die Instanz wieder, wenn sie verkleinert oder gelöscht werden soll. Löscht jemand die Instanz in der Konsole, meldet terraform plan die Abweichung und schlägt vor, sie neu zu erstellen.
Das Bild hat eine Grenze: Ein Grundbuch kann von Hand weitergeschrieben werden, der State nicht. Jede manuelle Änderung zerstört die Zuordnung. Deshalb gilt in der Praxis: State im verschlüsselten Backend (zentraler Ablageort) speichern, Zugriff strikt begrenzen.
Der State ist Terraforms Gedächtnis, kein Protokoll. Er wird geschützt, geteilt und nie von Hand editiert.
📌 State · Backend · Zuordnung
📚 Cloud von Grund auf · Tag 5 von 30
#Terraform #iac #CloudSecurity
Einem JWT begegnet man als Header der Form Authorization: Bearer, gefolgt vom Token, sobald eine API nach einem Login verlangt. Wer nicht weiß, was darin steht, legt unbemerkt Geheimnisse in den Payload offen.
Ein JWT ist ein Zugriffstoken aus drei Teilen, die mit Punkten verbunden sind: Header, Payload und Signatur. Alle drei sind Base64url-kodiert, also in druckbare Zeichen umgewandelt – das ist eine Kodierung, keine Verschlüsselung, und lässt sich ohne Schlüssel sofort zurückübersetzen.
Der Header ist ein JSON-Objekt mit Metadaten, vor allem dem Signaturverfahren im Feld alg. Die Payload ist ebenfalls JSON und enthält Claims, also Angaben wie Nutzerkennung oder Ablaufzeitpunkt. Der Claim exp gibt den Ablaufzeitpunkt als Unix-Zeit an, iat die Ausstellungszeit. Das Token an den Punkten trennen und die ersten beiden Teile zurückübersetzen: Nutzerkennung und Rollen stehen im Klartext. Die Signatur entsteht, weil der Aussteller Header und Payload mit einem nur ihm bekannten Schlüssel signiert. Ändert jemand die Payload, passt die Signatur nicht mehr – der Prüfer verwirft das Token.
Verwechselt wird das mit Verschlüsselung: Die Signatur macht kein Geheimnis aus dem Inhalt, sie belegt nur, dass genau dieser Aussteller genau diesen Inhalt erzeugt hat. Der Prüfer gibt nach RFC 8725 den Algorithmus fest vor und lehnt none ab.
Ein JWT ist kein Briefumschlag, sondern eine unterschriebene Postkarte: Inhalt offen lesbar, Absender beglaubigt. Deshalb gehören Passwörter und Geheimnisse nie in die Payload.
📌 Base64url · Claims · Signatur
📚 Webentwicklung von Grund auf · Tag 4 von 30
#WebSecurity #api #backend #webdev
Die Annahme klingt plausibel: JavaScript entstand für Webseiten, und dort sieht man es auch. Wer Buttons, Formulare und Animationen kennt, verbindet die Sprache fest mit Browser und Frontend.
Tatsächlich ist der Browser nur eine Laufzeitumgebung – also das Programm, das die Sprache überhaupt ausführen kann. Es enthält die Sprach-Engine und Bibliotheken, über die der Code sein Betriebssystem erreicht. Die Sprache selbst definiert die ECMAScript-Norm, und jede Umgebung legt fest, was sie darf. Node.js ist eine solche Umgebung und führt JavaScript außerhalb des Browsers aus, etwa auf einem Server. Sie ergänzt die Sprache um Module für Dateizugriffe und um eines, das einen HTTP-Server startet, der Anfragen entgegennimmt und antwortet.
Der Irrtum entsteht, weil Einsteiger JavaScript fast ausschließlich im Frontend erleben. Dort laufen die Sprache und der Browser scheinbar immer gemeinsam auf.
Ein kleines Skript zeigt den Unterschied: Unter Node.js liest es eine Datei ein und zählt Wörter. Genau dieses JavaScript hat vorher vielleicht einen Button im Browser verarbeitet. Wird daraus ein Server, beantwortet er etwa die Anfrage GET /artikel/42 mit einem Datensatz im JSON-Format.
Woran man es erkennt: Läuft Code ohne geöffnetes Browserfenster, ist er nicht im Frontend, sondern im Backend unterwegs. Frontend und Backend sind keine Ordner, sondern Lauforte derselben Sprache.
JavaScript heißt nicht „die Browsersprache“, sondern eine Sprache mit wechselnden Lauforten. Wer Werkzeuge wie npm nutzt, fährt bereits Node.js, ohne es zu bemerken.
📌 Laufzeitumgebung · Node.js · Frontend und Backend als Lauforte
📚 Webentwicklung von Grund auf · Tag 4 von 30
#javascript #NodeJS #webdev
Beide laufen direkt hintereinander ab und landen oft in einem Topf namens „Login“. Dabei können sie unabhängig scheitern – und der Server antwortet dann mit unterschiedlichen Fehlercodes.
Bei der Authentifizierung gleicht der Server eine Angabe wie Passwort oder Token (ein Ausweis-Datenstück aus Buchstaben und Zahlen) mit seinen gespeicherten Daten ab. Daraus ermittelt er eine Identität, etwa die Nutzer-ID 42. Das ist der erste Schritt: Ohne feststehende Identität kann keine Rechteprüfung folgen.
Bei der Autorisierung prüft der Server für jede einzelne Anfrage, ob diese Identität die angefragte Aktion ausführen darf. Konkret: Nutzer 42 meldet sich mit Passwort an. Beim Aufruf von DELETE /artikel/7 prüft der Server zusätzlich, ob 42 die Rolle Redakteur hat. Ohne diese Rolle folgt der Statuscode 403.
Scheitert die Authentifizierung, antwortet der Server mit 401 (nicht authentifiziert). Scheitert nur die Autorisierung, folgt 403 (verboten) – die Identität ist bekannt, aber die Rechte fehlen.
Weil HTTP zustandslos ist – jede Anfrage steht für sich –, muss jede Anfrage die Identität erneut belegen, etwa durch ein Cookie, ein Name-Wert-Paar, das der Server setzt und der Browser zurücksendet, mit einer Sitzungs-ID als Verweis auf die serverseitig gespeicherte Anmeldung. Der Server authentifiziert also bei jeder Anfrage von Neuem. Und weil der Browser-Seite nicht vertraut werden kann, gehört jede dieser Prüfregeln zusätzlich ins Backend.
Faustregel: Erst die Identität feststellen, dann je Anfrage die Rechte prüfen – beide Prüfungen niemals nur im Browser.
Authentifizierung heißt nicht „eingeloggt und alles erlaubt“, sondern nur „erkannt“. Was jemand darf, entscheidet die Autorisierung – separat und bei jedem Zugriff neu.
📌 Identität · Rechte · 401 vs. 403
📚 Webentwicklung von Grund auf · Tag 4 von 30
#WebSecurity #backend #HTTP
Ein Cache ist eine gespeicherte Kopie einer HTTP-Antwort, die wiederverwendet wird, statt sie jedes Mal neu vom Server zu laden. Ob und wie lange eine gespeicherte Kopie wiederverwendet werden darf, steuert der Server über den Header Cache-Control in der Antwort selbst. Wer no-cache falsch versteht, verschickt versehentlich vertrauliche Daten in Caches – oder wundert sich, dass die Rückfrage trotzdem kommt.
no-cache heißt nicht „nicht speichern“, sondern „vor jeder Wiederverwendung beim Server validieren“. Die Antwort darf also im Cache liegen. Bevor der Browser sie erneut anzeigt, muss er aber beim Server nachfragen, ob sie sich verändert hat.
Konkret läuft diese Nachfrage als bedingter Request: Der Browser sendet einen gespeicherten ETag – einen vom Server vergebenen Prüfwert für eine Darstellung – im Header If-None-Match mit. Ist die Ressource unverändert, antwortet der Server nur mit 304 Not Modified und leerem Body. Der Browser nutzt dann seine gespeicherte Kopie weiter. Eine HTML-Seite mit no-cache und ETag bleibt so immer aktuell, während nur wenige Bytes über die Leitung gehen. Wer dagegen aktuelle Daten ohne Rückfrage zulassen will, setzt max-age=N: Dann darf der Cache die Antwort N Sekunden lang ausliefern, ohne zu fragen.
Verwechselt wird no-cache vor allem mit no-store. Letzteres verbietet jede Speicherung und gehört zu persönlichen Daten wie Bankauszügen oder Sitzungsdaten. no-cache hält eine Seite dagegen aktuell, ohne sie jedes Mal komplett neu zu laden – ein Geschwindigkeitsgewinn, kein Nachteil.
no-cache ist nicht „nicht speichern“, sondern „speichern, aber vorher fragen“. Wer nichts gespeichert haben will, schreibt no-store.
📌 Cache-Control · no-cache · no-store
📚 Webentwicklung von Grund auf · Tag 3 von 30
#webdev #HTTP #backend #performance
Der Browser vergleicht bei jeder Antwort, ob sie von derselben Origin (der Kombination aus Schema, Host und Port) stammt wie die Seite, deren JavaScript sie lesen will. Das begegnet Einsteigern sofort, sobald Frontend und Backend getrennt laufen.
Zuerst lädt der Browser die Seite, etwa eine gewöhnliche Dokumentseite unter https. JavaScript auf dieser Seite ruft dann Daten ab, zum Beispiel von einer API unter einem anderen Host. Die Anfrage geht ganz normal raus; der Server antwortet, ohne zu prüfen, wer sie liest.
Dann zählt der Browser Schema, Host und Port, nicht den Pfad: Zwei Adressen wie /seite1 und /api/daten auf demselben Host mit demselben Port teilen sich eine Origin. Aber ein API-Host und ein www-Host derselben Domain sind verschiedene Hosts, und derselbe Host mit abweichendem Port wie 8443 ist eine andere Origin. Ein fehlender Port bedeutet den Standardport, also 443 bei https.
Danach hält der Browser die Antwort zurück, wenn die Origins verschieden sind. Der Browser schickt die Anfrage, gibt die Antwort aber nicht an JavaScript weiter, solange der Server sie nicht per CORS (einem Header-Mechanismus zur Freigabe) erlaubt. Bilder und Stylesheets fremder Origins erscheinen trotzdem, weil kein Skript ihren Inhalt liest.
Zuletzt gilt die Grenze nur im Browser. curl (ein Kommandozeilenwerkzeug für HTTP-Anfragen) sendet und liest ohne Sandbox alles; die Same-Origin-Policy schützt den Server nicht, nur die Seite im Browser.
Gleiche Origin heißt also nicht gleicher Host, und fremde Origin heißt nicht blockierte Anfrage – sondern unlesbare Antwort.
📌 Origin · Same-Origin-Policy · CORS
📚 Webentwicklung von Grund auf · Tag 3 von 30
#WebSecurity #webdev #javascript
Der Transporter fährt durch offenes Gelände. Beobachter sehen den Wagen, erkennen aber keinen Inhalt. Wird eine Kiste unterwegs aufgebrochen, fällt der Eingriff sofort auf.
Technisch ist HTTPS HTTP über TLS, also das normale Web-Protokoll über eine verschlüsselte Verbindung. Der TLS-Handshake, die Verbindungsaufnahme, einigt sich auf einen Schlüssel und prüft das Zertifikat: ein digitaler Ausweis, den eine Zertifizierungsstelle als anerkannte Vertrauensinstanz signiert hat. Der Browser vergleicht den Domainnamen im Zertifikat mit dem Host der URL, also dem Domainnamen in der Adresse; danach laufen alle Anfragen und Antworten als Chiffretext, also unlesbarer Geheimtext.
Beim Aufruf ist das Schema der URL der Teil vor dem Doppelpunkt: Es sagt dem Client, welches Protokoll er nutzt. Aus http wird damit https: verschlüsselte Übertragung mit Geheimhaltung, statt Klartext. Das Schloss im Browser bedeutet also nicht „sicherer Server“, sondern belegt nur zwei Eigenschaften des Wegs: verschlüsselte Übertragung und geprüfte Identität.
Das Bild hat eine Grenze: Der Transporter schützt weder das Lager noch die Ware nach der Abladung. Nach dem Entschlüsseln liegen die Daten auf dem Server im Klartext vor; Angriffe im Backend liegen außerhalb der Zuständigkeit der Verbindung.
HTTPS heißt nicht „dieser Server ist gut“, sondern „dieser Weg ist verschlüsselt, und dieser Ausweis passt zur Domain“.
📌 TLS-Verschlüsselung · Zertifikat · Schloss-Symbol
📚 Webentwicklung von Grund auf · Tag 3 von 30
#WebSecurity #HTTP #webdev
Nach dem Schließen und Wiederöffnen des Browsers ist der Nutzer abgemeldet. Beim Klick durch die Seiten ist dagegen alles normal.
Ein Cookie ist ein Name-Wert-Paar, das der Server mit dem Header Set-Cookie setzt und das der Browser bei passenden Anfragen im Header Cookie zurücksendet. Header sind Zeilen, die bei HTTP Daten zwischen Server und Browser austauschen; HTTP selbst ist zustandslos, jede Anfrage steht für sich. Der Server erkennt Nutzer also nur anhand mitgesendeter Werte wie Cookies, etwa als Schlüssel in seiner Session-Tabelle. Ohne Expires und Max-Age entsteht ein Sitzungscookie: Der Browser verwirft es beim Schließen, kann die Sitzung aber wiederherstellen. Mit Expires, einem konkreten Ablaufdatum, oder Max-Age, einer Lebensdauer in Sekunden, entsteht ein dauerhaftes Cookie, das Neustarts überlebt; ist beides gesetzt, gewinnt Max-Age.
Set-Cookie: sessionid=abc123; Path=/; HttpOnly setzt ein Sitzungscookie, das beim Beenden des Browsers verschwindet. Fügt man Max-Age=3600 an, bleibt es eine Stunde lang bestehen. Der Nutzer bleibt dann auch nach einem Neustart angemeldet – bis die Frist abläuft.
So prüft man es: Im Browser-DevTools unter Application die Cookies der Seite ansehen und die Spalten Expires und Max-Age prüfen. Sitzungscookies zeigen dort „Session“ statt eines Datums.
Sitzungscookie meint hier nur die Speicherung im Browser, nicht eine Server-Session; auch ein dauerhaftes Cookie kann einen Sitzungsschlüssel tragen, den der Server jederzeit für ungültig erklärt. Expires und Max-Age sind also die Schalter für die Lebensdauer, nicht für den Inhalt.
📌 Sitzungscookie · Max-Age · dauerhaftes Cookie
📚 Webentwicklung von Grund auf · Tag 3 von 30
#webdev #HTTP #WebSecurity #backend
HTTP, das Protokoll hinter Webseiten, ist zustandslos – jede Anfrage steht für sich. Ohne zurückgesendete Daten wüsste der Server nicht, wer fragt. Cookies füllen genau diese Lücke.
🌐 Ein Cookie ist ein Name-Wert-Paar, das der Server setzt. In der Antwort steht etwa: Set-Cookie: sessionid=abc123; Path=/; HttpOnly. Vor dem Semikolon stehen Name und Wert, die Attribute dahinter steuern Speicherung und Versand. Path=/ bedeutet: zu jedem Pfad dieses Hosts mitsenden.
🧩 Der Browser schickt das Cookie automatisch mit, ohne eigenes Programm. Passt die angefragte Adresse zum Cookie, fügt der Browser den Header Cookie: sessionid=abc123 in die Anfrage ein. Die Webanwendung muss nichts dafür tun. Derselbe Datensatz heißt in der Antwort Set-Cookie, in der Anfrage Cookie – zwei Header, ein Inhalt. Nachvollziehen lässt sich das in den Entwicklerwerkzeugen: im Netzwerk-Tab bei einer Antwort den Set-Cookie-Header suchen und bei der nächsten Anfrage an denselben Host den Cookie-Header mit demselben Wert vergleichen.
🔒 HttpOnly schützt den Cookie vor JavaScript im Browser. JavaScript kann ihn dann nicht auslesen, und ein XSS-Angriff (böses Skript auf der Seite) stiehlt ihn nicht direkt. Ohne Expires oder Max-Age gilt das Cookie nur bis zum Schließen des Browsers. Das nennt man Sitzungscookie; der Browser kann die Sitzung aber wiederherstellen.
Ein Cookie heißt nicht Abfrage durch den Server, sondern automatischer Rückversand durch den Browser. Der Server erkennt Nutzer wieder, indem er den Wert etwa in seiner Session-Tabelle nachschlägt.
📌 Name-Wert-Paar · Set-Cookie · automatischer Rückversand
📚 Webentwicklung von Grund auf · Tag 2 von 30
#webdev #HTTP #backend
Wer das erste Mal eine Anmeldung baut, stolpert fast immer hier. Wer nicht weiß, dass HTTP zustandslos ist, wundert sich, warum der Nutzer nach einem Klick wieder ausgeloggt ist.
Zustandslos heißt: Jede HTTP-Anfrage (die Nachricht, die der Browser an den Server schickt) steht für sich allein. Sie besteht aus Methode, Ziel, Headern und optionalem Body. Das Protokoll kennt keine Verbindung zwischen zwei Anfragen. Aus Sicht des Servers ist jede Anfrage die erste. Zustandslos heißt also nicht, dass der Server kein Gedächtnis haben darf. Nur das Protokoll selbst verknüpft nichts.
Die Erinnerung liefert der Client mit: eine Kennung, die bei jeder Anfrage mitgeschickt wird. Nach dem Login antwortet der Server etwa mit dem Header Set-Cookie: session=abc123. Der Browser speichert dieses Name-Wert-Paar und sendet es bei passenden Anfragen im Header Cookie: session=abc123 zurück. Der Server findet dazu die Sitzung mit dem Login-Zustand. Fehlt die Kennung, etwa weil Cookies gelöscht wurden, gilt die nächste Anfrage als die eines unbekannten Besuchers. Eine Alternative zum Cookie ist ein Token, eine Zeichenkette, die der Client beim Aufruf einer API selbst in einen Header setzt. Auch sie wirkt nur, weil sie jedes Mal erneut mitgesendet wird.
Verwechselt wird Zustandslosigkeit gern mit fehlender Authentifizierung, der Frage, wer jemand ist. Beides ist unabhängig: Auch nach erfolgreichem Login bleibt jede Anfrage für sich. Die Kennung muss trotzdem überall mitgeschickt werden.
HTTP ist nicht vergesslich, sondern absichtlich gedächtnislos. Die Sitzung entsteht erst durch die Kennung, die jede Anfrage mitbringt.
📌 Zustandslos · Cookie · Session-ID
📚 Webentwicklung von Grund auf · Tag 2 von 30
#webdev #HTTP #backend
Viele Einsteiger halten GET und POST für zwei gleichwertige Türen: Hauptsache, die Anfrage kommt beim Server an. Das klingt plausibel, weil beide Daten transportieren können.
Tatsächlich unterscheidet RFC 9110, die aktuelle HTTP-Spezifikation, die Methoden nach zwei Eigenschaften. Sicher heißt: Die Methode verändert den Zustand des Servers nicht; GET, HEAD, OPTIONS und TRACE sind sicher. Idempotent heißt: Mehrere identische Anfragen wirken wie eine einzige; das gilt für PUT, DELETE und alle sicheren Methoden. POST und PATCH fallen heraus: Ein wiederholter POST kann eine zweite Ressource anlegen, etwa eine doppelte Bestellung.
Der Irrtum entsteht, weil HTML-Formulare nur GET und POST anbieten. Wer keine anderen Methoden kennt, wählt nach Syntax statt nach Bedeutung.
Eine Bestellung per GET zu senden endet im Browser-Cache: GET-Anfragen dürfen vorabgeladen oder zwischengespeichert werden; das kann unbeabsichtigte Ausführungen auslösen. Korrekt ist POST für die Erzeugung; wer POST wiederholbar machen will, sendet zusätzlich einen Idempotenz-Schlüssel. Das ist ein eindeutiger Wert, etwa eine UUID, im Request-Header; der Server speichert Schlüssel und Antwort und liefert bei Wiederholung dieselbe Antwort zurück.
Woran man es erkennt: Verändert die Anfrage etwas auf dem Server, reicht GET nie aus. Regel: Lesen mit GET, Erzeugen mit POST, vollständiges Ersetzen mit PUT.
Sicher heißt nicht wirkungslos, sondern nebenwirkungsfrei. Idempotent heißt nicht wirkungslos, sondern ohne Doppelwirkung.
📌 Sichere Methoden · Idempotenz · Idempotenz-Schlüssel
📚 Webentwicklung von Grund auf · Tag 2 von 30
#HTTP #REST #webdev #backend
Jede Serverantwort im Web beginnt mit einem Statuscode, einer dreistelligen Nummer. Sie tritt überall auf: beim Aufruf einer Seite, beim Bookmark im Browser, beim Newsletter-Feed. Die erste Ziffer gibt die Klasse an, hier 4 für einen Fehler des Clients.
Zuerst sendet der Client eine Anfrage an eine URL, also eine Adresse im Web. Der Server sucht die angeforderte Ressource – eine Seite, ein Bild, einen Datensatz. Findet er sie nicht, antwortet er mit 404 Not Found.
Dann entscheidet der Client, was das bedeutet. Die erste Ziffer der Nummer nennt nur die Richtung: Bei 4xx liegt der Fehler meist in der eigenen Anfrage, etwa in einer falschen URL oder fehlender Berechtigung. Der Haken bei 404: Die Nummer sagt nichts über die Zukunft. Die Adresse kann nie existiert haben, vertippt sein oder erst morgen wieder erreichbar sein. Für den Client ist eine Löschung ununterscheidbar von einem Tippfehler in der URL.
Danach gibt es für den Fall der bewussten Löschung eine klarere Antwort: 410 Gone. Sie bedeutet, die Ressource existierte einst, wurde aber absichtlich und dauerhaft entfernt. Der Server weiß das und teilt es ausdrücklich mit.
Zuletzt kann der Client auf 410 höflicher reagieren: Ein Feed-Leser darf den Link als endgültig tot markieren und seine Wiederholungen einstellen. Bei 404 bleibt dagegen nur: immer wieder probieren. Praxisregel für eigene Backends: Nach dem Löschen einer Ressource 410 senden; 404 bleibt für unbekannte oder nie existierte Adressen.
404 heißt also nicht „gelöscht“, sondern „gerade nicht gefunden“ – erst 410 spricht von dauerhaft weg.
📌 Statuscode · 404 Not Found · 410 Gone
📚 Webentwicklung von Grund auf · Tag 2 von 30
#webdev #HTTP #backend
Beide beginnen mit 4 und gehören zur Klasse 4xx, also Fehlern in der Anfrage des Clients. Der Rumpf der Nummer unterscheidet dann, was genau schiefging.
401 Unauthorized heißt trotz seines Namens „nicht angemeldet“. Der Server kennt die Identität des Anfragenden nicht oder hält den Nachweis für ungültig; Authentifizierung ist genau dieses Prüfen, wer jemand ist, etwa per Login-Token. Deshalb schickt der Server im WWW-Authenticate-Header mit, welche Anmeldeverfahren er akzeptiert. Beispiel: Ein Aufruf von DELETE /users/42 ohne Token bekommt 401 samt Hinweis auf das Login-Verfahren.
403 Forbidden heißt „nicht erlaubt“. Der Server weiß zwar, wer anfragt, aber diese Person darf die Ressource nicht sehen; Autorisierung ist dieses Prüfen, was jemand tun darf. Ein erneutes Anmelden hilft nicht. Beispiel: Eine Nutzerin mit gültigem Token, aber ohne Admin-Rolle, ruft DELETE /users/42 auf und bekommt 403.
Der entscheidende Unterschied liegt also in der Identität: Bei 401 fehlt der Nachweis, wer anfragt, bei 403 ist der Nachweis da, aber die Erlaubnis fehlt. Verbreiteter Irrtum: Ein falsches Passwort gehört zur fehlenden Authentifizierung und damit zu 401, nicht zu 403.
Faustregel: Im eigenen Backend bei fehlendem oder ungültigem Token 401 zurückgeben, bei gültigem Token ohne ausreichende Rolle 403. Manche Backends antworten auf fehlende Berechtigung mit 404, um die Existenz einer Ressource nicht zu verraten; fürs Lernen genügt die klare Trennung.
401 heißt nicht „verboten“, sondern „erst anmelden“ – 403 heißt „angemeldet, aber nicht erlaubt“.
📌 401 = Anmeldung fehlt · 403 = Erlaubnis fehlt · WWW-Authenticate-Header
📚 Webentwicklung von Grund auf · Tag 2 von 30
#HTTP #REST #WebSecurity
Wer nicht weiß, welcher Baustein wo läuft, baut Prüfregeln an den falschen Ort. Und der falsche Ort ist der, den jeder Besucher verändern kann.
🌐 Frontend und Backend sind keine Ordner, sondern Lauforte. Das Frontend ist der Teil, der im Browser läuft: HTML beschreibt die Struktur, CSS das Aussehen, JavaScript das Verhalten auf der Seite. Das Backend läuft auf dem Server, speichert Daten und stellt Schnittstellen bereit. Dieselbe Sprache JavaScript kann an beiden Orten laufen: im Browser oder mit Node.js auf dem Server.
🧩 Der Browser spricht mit dem Backend über HTTP, das Anfrage-Antwort-Protokoll des Webs. Eine Schnittstelle (API) liefert etwa mit GET /artikel/42 einen Datensatz, oft als JSON, einem einfachen Textformat für Daten. Der Server kann dieselbe Adresse unterschiedlich beantworten: dem Browser eine HTML-Seite, einem Programm JSON-Daten. Er weiß dabei nie, was gerade angezeigt wird; jede Anfrage muss alles enthalten, was er zum Prüfen braucht.
🔒 Sensible Daten und alle Prüfregeln gehören immer ins Backend. Der JavaScript-Code im Browser ist sichtbar und veränderbar. Ein Kontaktformular prüft dort per JavaScript, ob das E-Mail-Feld ausgefüllt ist, und markiert den Fehler sofort. Das Backend prüft dieselbe Eingabe trotzdem erneut, weil die Frontend-Prüfung mit den Entwicklerwerkzeugen abgeschaltet sein kann.
Frontend heißt nicht „der sichere Teil der Anwendung“, sondern der Teil auf dem Gerät des Besuchers. Deshalb gilt: Ob eine Eingabe gilt, prüft der Server, nicht der Browser.
📌 Frontend · Backend · Serverprüfung
📚 Webentwicklung von Grund auf · Tag 2 von 30
#frontend #backend #webdev
Man begegnet ihnen bei jeder Seite im Browser. Wer die Trennung nicht kennt, ändert später jede Datei einzeln und sammelt Fehler, statt sie zu vermeiden.
Das Frontend, also der Teil einer Anwendung, der im Browser läuft, nutzt drei Sprachen mit getrennten Aufgaben. HTML beschreibt Struktur und Inhalt, CSS das Aussehen, JavaScript das Verhalten. HTML ist eine Auszeichnungssprache: Elemente wie Überschriften und Links teilen dem Browser mit, welche Bedeutung ein Textteil hat. CSS besteht aus Regeln mit Selektor, der bestimmt, welche Elemente gemeint sind, und Deklarationen wie color: red, die das Aussehen festlegen. JavaScript ist eine Programmiersprache und reagiert etwa auf Klicks, ohne die Seite neu zu laden.
Ein Beispiel: ein Button, in HTML mit dem button-Element ausgezeichnet, sagt dem Browser „hier steht etwas Klickbares“. Eine CSS-Regel färbt seine Schrift rot, etwa mit color: red. Ein Klick darauf löst JavaScript aus, das per Programmierung ein Dankeschön einblendet. Drei Dateien, drei Aufgaben, ein zusammenwirkendes Ergebnis.
Verwechselt wird die Trennung oft mit der zwischen Frontend und Backend. Das Backend läuft auf dem Server, speichert Daten und stellt Schnittstellen bereit. Hier geht es aber um die Rollen innerhalb einer einzigen HTML-Seite im Browser. Der typische Irrtum: Aussehen direkt in HTML-Attribute schreiben. Dann muss man bei einer Designänderung jede Seite einzeln anfassen; mit getrennter CSS-Datei genügt eine Änderung für alle.
HTML ist also nicht der Ort für Farben oder Logik, sondern nur für Bedeutung und Struktur. Wer die Aufgaben trennt, wartet eine Änderung an genau einer Stelle.
📌 HTML · CSS · JavaScript
📚 Webentwicklung von Grund auf · Tag 1 von 30
#webdev #frontend #javascript
Einsteiger denken so, weil Adressen wie /artikel/42 wie Dateipfade aussehen. Das klingt plausibel, schließlich arbeitet man im Betriebssystem tagtäglich mit Ordnern.
Tatsächlich besteht eine URL aus mehreren Teilen: Schema, Host, optionalem Port, Pfad, optionaler Query und optionalem Fragment. Das Schema etwa https sagt dem Client, also dem Browser, welches Protokoll er für die Verbindung nutzt. Der Host nennt den Server, und der Pfad benennt die Ressource, die angefragt wird. Der Server vergleicht den Pfad mit seinen hinterlegten Routen und antwortet mit 404, wenn keine passt.
Der Irrtum entsteht, weil URLs oft so aussehen wie Dateipfade. Server dürfen den Pfad aber beliebig deuten; eine Ordnung dahinter ist reine Konvention.
Nehmen wir eine Adresse mit dem Pfad /artikel/42 und der Query ?sort=neu&page=2. Der Browser baut daraus die Anfrage an den Server des Hosts, über HTTPS verschlüsselt. Der Pfad wählt die Ressource, die Query-Parameter als Name-Wert-Paare liefern zusätzliche Angaben wie Filter oder Sortierung. Passt keine Route, antwortet der Server mit 404 statt 200.
Woran man es erkennt: Der Server antwortet auf jeden Pfad nach eigenen Regeln, nicht nach Dateisystem-Lookup. Ein Fragment nach der Raute wird gar nicht erst mitgesendet, weil es eine Stelle innerhalb der Seite bezeichnet.
Der Pfad heißt nicht Ordnerstruktur auf dem Server, sondern ein Bezeichner für die Ressource, deren Deutung beim Server liegt.
📌 Schema · Host · Pfad · Query-Parameter
📚 Webentwicklung von Grund auf · Tag 1 von 30
#webdev #HTTP #backend
Erklärt wird das Anfrage-Antwort-Muster des Webs: Der Client fragt, der Server antwortet. Es passiert bei jedem Seitenaufruf, ob Browser, Smartphone-App oder Kommandozeile.
Zuerst tippt jemand eine Adresse ein, etwa eine mit Schema https, einem Host und dem Pfad zu einem Artikel. Der Browser zerlegt sie: Das Schema nennt die Art des Zugriffs, der Host den Zielrechner, der Pfad die Ressource. Der Browser ist hier der Client, also das Programm, das fragt. Das muss kein Browser sein; auch curl oder eine Mobile-App können diese Rolle übernehmen.
Dann baut der Client daraus eine HTTP-Anfrage, die Nachrichtenform des Webs. Sie besteht aus Methode, Ziel, Headern und optionalem Body. Die Methode sagt, was gewollt ist, etwa GET für reines Abfragen. Header sind kleine Zusatzinformationen.
Danach sendet der Client diese Anfrage an den Server, also das Programm, das antwortet. Der Server wartet nur; von sich aus schickt er nichts. Ohne vorherige Anfrage kommt keine Nachricht zurück. Die Begriffe Client und Server bezeichnen Rollen, keine Geräte. Wer fragt, bleibt in diesem Vorgang Client, auch wenn die Antwort aus Daten besteht.
Zuletzt antwortet der Server mit Statuscode, Headern und optionalem Body. Der Statuscode 200 meldet Erfolg, 404, dass der Server die Ressource unter diesem Pfad nicht findet. Die Antwort ist eine Darstellung der Ressource, etwa HTML für den Browser oder JSON-Daten für ein Programm. Da HTTP zustandslos ist, muss jede Anfrage alles nennen, was der Server zum Antworten braucht. Der Server weiß nie, was der Browser gerade anzeigt.
Wer denkt, Server könnten pushen, verwechselt Muster mit Ausnahmen.
📌 Anfrage-Antwort-Muster · Client und Server · Ressource und Darstellung
📚 Webentwicklung von Grund auf · Tag 1 von 30
#webdev #HTTP #backend