`Cookie` in TypeScript
Dieser Artikel erklärt Cookie in TypeScript.
Wir gehen praxisnahe Muster durch, um Cookies sowohl im Browser als auch auf dem Server sicher und zuverlässig zu behandeln.
YouTube Video
Cookie in TypeScript
Grundkonzepte von Cookies
Ein Cookie ist ein Mechanismus zum Speichern kleiner Zeichenketten (Name=Wert-Paare) auf dem Client, erstellt über den HTTP-Header Set-Cookie oder document.cookie. Ihr Verhalten lässt sich mit Sicherheitsattributen steuern (HttpOnly, Secure, SameSite usw.).
Grundlegende Operationen im Browser: document.cookie
Unten steht ein minimales Beispiel, um im Browser ein Cookie zu schreiben. Erstellen Sie ein Cookie, indem Sie eine Zeichenkette an document.cookie anhängen.
1// Set a simple cookie that expires in 7 days.
2// Note: Comments are in English per the user's preference.
3const setSimpleCookie = (name: string, value: string) => {
4 const days = 7;
5 const expires = new Date(Date.now() + days * 86400_000).toUTCString();
6 // name=value; Expires=...; Path=/
7 document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; Expires=${expires}; Path=/`;
8};
9
10setSimpleCookie('theme', 'dark');- Dieser Code erzeugt ein Cookie, das in 7 Tagen abläuft. Es ist auf der Browserseite leicht zu verwenden, aber da Sie
HttpOnlynicht setzen können, sollten Sie keine sensiblen Informationen speichern.
Cookies lesen (Browser)
Die folgende Funktion ist eine Hilfsfunktion, die den Wert des Cookies mit einem bestimmten Namen aus document.cookie abruft. document.cookie wird als Zeichenkette zurückgegeben, die durch Semikolon und Leerzeichen ('; ') getrennt ist. Daher teilen wir sie auf und suchen nach dem gewünschten Cookie.
1// Parse document.cookie and return value for given name or null if not found.
2const getCookie = (name: string): string | null => {
3 const cookies = document.cookie ? document.cookie.split('; ') : [];
4 for (const cookie of cookies) {
5 const [k, ...rest] = cookie.split('=');
6 const v = rest.join('=');
7 if (decodeURIComponent(k) === name) {
8 return decodeURIComponent(v);
9 }
10 }
11 return null;
12};
13
14// Example usage:
15const theme = getCookie('theme'); // => "dark" if set
16console.log('theme cookie:', theme);- Diese Funktion dekodiert sowohl den Cookie-Namen als auch den Cookie-Wert, um sie sicher zu vergleichen und abzurufen. Sie behandelt doppelte Cookie-Namen und kodierte Sonderzeichen und ist dadurch eine einfache, aber robuste Implementierung.
Sicherheitsattribute verstehen und anwenden
Cookies besitzen mehrere wichtige Attribute, die jeweils Sicherheit und Geltungsbereich des Verhaltens steuern.
- Das Attribut
HttpOnlyverhindert, dass das Cookie über JavaScript zugänglich ist, und hilft, XSS (Cross-Site Scripting)-Angriffe abzumildern. Beachten Sie, dassHttpOnlyclientseitig im Browser nicht gesetzt werden kann. - Das Attribut
Securebewirkt, dass Cookies nur über HTTPS gesendet werden, wodurch das Risiko von Abhören und Manipulation verringert wird. - Das Attribut
SameSitesteuert, ob Cookies bei seitenübergreifenden Anfragen gesendet werden, und hilft, CSRF (Cross-Site Request Forgery)-Angriffe zu verhindern. - Das Attribut
Pathlegt den Geltungsbereich der Anforderungspfade fest, für die das Cookie gesendet wird, und das AttributDomaingibt die Domain an, in der das Cookie gültig ist. - Durch Setzen der Attribute
ExpiresoderMax-Agekönnen Sie die Ablaufzeit des Cookies steuern.
Beispiel zum Setzen von SameSite/Secure im Browser (was möglich ist)
HttpOnly kann clientseitig nicht gesetzt werden. Im Folgenden ein Beispiel für das clientseitige Hinzufügen von SameSite und Secure. Allerdings wirkt Secure nur auf HTTPS-Seiten.
1// Set cookie with SameSite and Secure attributes (Secure only effective over HTTPS).
2const setCookieWithAttributes = (name: string, value: string) => {
3 const maxAge = 60 * 60 * 24 * 7; // 7 days in seconds
4 // Note: HttpOnly cannot be set from JS; set it on server-side when you want to restrict JS access.
5 document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; `
6 + `Max-Age=${maxAge}; `
7 + `Path=/; `
8 + `SameSite=Lax; `
9 + `Secure`;
10};
11
12setCookieWithAttributes('session_hint', 'true');SameSite=Laxist eine sichere und verbreitete Wahl. Für stärkere Einschränkungen verwenden SieSameSite=Strict, allerdings können legitime Navigationsvorgänge von externen Seiten nicht mehr funktionieren.
Cookies auf dem Server setzen (Set-Cookie) (Node/TypeScript)
Auf dem Server können Sie HttpOnly über den Set-Cookie-Header setzen; daher sollte das Sitzungsmanagement idealerweise serverseitig erfolgen. Unten ein Beispiel mit Nodes http-Modul.
1// A minimal Node HTTP server in TypeScript that sets a secure HttpOnly cookie.
2// This example uses built-in 'crypto' for a random session id.
3import http from 'http';
4import crypto from 'crypto';
5
6const server = http.createServer((req, res) => {
7 if (req.url === '/login') {
8 const sessionId = crypto.randomBytes(16).toString('hex');
9 // Set cookie with HttpOnly, Secure, SameSite and Path
10 // Expires is optional — Max-Age preferred for relative lifetimes.
11 res.setHeader('Set-Cookie', `sid=${sessionId}; `
12 + `HttpOnly; `
13 + `Secure; `
14 + `SameSite=Strict; `
15 + `Path=/; `
16 + `Max-Age=3600`
17 );
18 res.writeHead(302, { Location: '/' });
19 res.end();
20 return;
21 }
22
23 res.writeHead(200, { 'Content-Type': 'text/plain' });
24 res.end('Hello\n');
25});
26
27server.listen(3000, () => {
28 console.log('Server running on http://localhost:3000');
29});- Wenn Sie das Attribut
HttpOnlyserverseitig setzen, ist das Cookie von JavaScript aus nicht mehr zugänglich, was es XSS (Cross-Site Scripting)-Angriffen erschwert, es zu stehlen. Zusätzlich können Sie durch das Hinzufügen des AttributsSecure, sodass Cookies stets über HTTPS gesendet werden, Abhören und Manipulation verhindern und die Kommunikationssicherheit verbessern.
Implementierung für Cookie-Serialisierung/-Parsing (ein serverseitiger Helfer)
Nachfolgend eine einfache serverseitige Hilfsfunktion, die einen Set-Cookie-Header-String erzeugt.
1// Cookie serialization helper for server-side use.
2// Returns a properly formatted Set-Cookie header value.
3type CookieOptions = {
4 path?: string;
5 domain?: string;
6 maxAge?: number;
7 expires?: Date;
8 httpOnly?: boolean;
9 secure?: boolean;
10 sameSite?: 'Strict' | 'Lax' | 'None';
11};
12
13const serializeCookie = (name: string, value: string, opts: CookieOptions = {}): string => {
14 const parts: string[] = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
15
16 if (opts.maxAge != null) parts.push(`Max-Age=${Math.floor(opts.maxAge)}`);
17 if (opts.expires) parts.push(`Expires=${opts.expires.toUTCString()}`);
18 if (opts.domain) parts.push(`Domain=${opts.domain}`);
19 parts.push(`Path=${opts.path ?? '/'}`);
20 if (opts.httpOnly) parts.push('HttpOnly');
21 if (opts.secure) parts.push('Secure');
22 if (opts.sameSite) parts.push(`SameSite=${opts.sameSite}`);
23
24 return parts.join('; ');
25};
26
27// Example usage:
28const headerValue = serializeCookie('uid', 'abc123', {
29 httpOnly: true,
30 secure: true,
31 sameSite: 'Lax',
32 maxAge: 3600
33});
34console.log(headerValue);
35// => "uid=abc123; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Lax"
- Dieses Hilfsprogramm bildet die Grundlage für das Erstellen von
Set-Cookieauf einem eigenen Server. Bibliotheken decken weitaus mehr Randfälle ab.
Manipulationsschutz mit Signaturen (HMAC)
Es ist gefährlich, wichtige Werte direkt in Cookies zu speichern. Wir stellen eine Methode vor, die Werte serverseitig signiert, um Manipulationen zu erkennen. Hier verwenden wir HMAC-SHA256. Im Produktionsbetrieb müssen Sie den Token-Widerruf ebenfalls serverseitig verwalten.
1// A simple HMAC signing and verification helper for cookies.
2// Signing prevents client from tampering cookie values.
3import crypto from 'crypto';
4
5const SECRET = 'replace_with_env_secret'; // store in env var in production
6
7const signValue = (value: string) => {
8 const hmac = crypto.createHmac('sha256', SECRET);
9 hmac.update(value);
10 return `${value}.${hmac.digest('hex')}`;
11};
12
13const verifySignedValue = (signed: string): string | null => {
14 const idx = signed.lastIndexOf('.');
15 if (idx === -1) return null;
16 const value = signed.slice(0, idx);
17 const sig = signed.slice(idx + 1);
18
19 const hmac = crypto.createHmac('sha256', SECRET);
20 hmac.update(value);
21 const expected = hmac.digest('hex');
22 // use timing-safe comparison in production
23 if (crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
24 return value;
25 }
26 return null;
27};
28
29// Example usage:
30const signed = signValue('userId=42');
31console.log('signed:', signed);
32console.log('verified:', verifySignedValue(signed)); // => "userId=42"
- Mit dieser Methode können Sie prüfen, ob der Cookie-Wert manipuliert wurde. Fügen Sie den Signierschlüssel nicht in den Quellcode ein; verwalten Sie ihn auf sichere Weise, zum Beispiel über Umgebungsvariablen.
Cookies und CSRF-Abwehr (allgemeine Muster)
Sitzungen, die Cookies verwenden, benötigen CSRF-Schutz. Typische Gegenmaßnahmen sind:.
- Setzen Sie
SameSiteaufLaxoderStrict, um unnötiges Senden über Websites hinweg zu verhindern. Verwenden SieSameSite=None; Securenur, wenn eine ursprungsübergreifende Kommunikation erforderlich ist. - Verwenden Sie CSRF-Token, die vom Server validiert werden, für Formulare und API-Anfragen. Speichern Sie das Token nicht in einem
HttpOnly-Cookie; stellen Sie es stattdessen über den Antwortkörper oder Meta-Tags bereit und lassen Sie JavaScript es nur bei Bedarf auslesen. - Wenn auf das Token aus JavaScript zugegriffen werden kann, stellen Sie sicher, dass zudem XSS-Schutzmaßnahmen (CSP, Output-Escaping usw.) implementiert sind.
- Verlangen Sie für sensible Aktionen und bei der Anmeldung eine erneute Authentifizierung und verhindern Sie Session-Fixation-Angriffe.
Im Folgenden finden Sie ein sicheres Client-Beispiel, das das CSRF-Token in einem Header sendet. Dabei wird angenommen, dass der Client das Token bereits vom Server erhalten hat, z. B. im Antwortkörper.
1// Example of sending CSRF token safely in a header using fetch.
2// Assumes CSRF token was provided securely (e.g., via response body or meta tag).
3async function sendProtectedRequest(url: string, csrfToken: string) {
4 const res = await fetch(url, {
5 method: 'POST',
6 credentials: 'same-origin', // include cookies for same-site requests
7 headers: {
8 'Content-Type': 'application/json',
9 'X-CSRF-Token': csrfToken
10 },
11 body: JSON.stringify({ action: 'doSomething' })
12 });
13 return res;
14}- Wenn Sie
credentials: 'same-origin'angeben, werden nur Cookies für dieselbe Herkunft gesendet. Validieren Sie auf dem Server den Wert desX-CSRF-Token-Headers und verifizieren Sie, dass das Token übereinstimmt. Wenn Cross-Site-Anfragen erforderlich sind, konfigurieren Sie CORS sorgfältig.
Cross-Site (CORS) und der Zusammenhang mit credentials
Um Cookies in einer ursprungsübergreifenden Kommunikation zu senden und zu empfangen, muss der Client credentials: 'include' angeben und der Server Access-Control-Allow-Credentials: true setzen. Beschränken Sie diese Konfiguration jedoch auf vertrauenswürdige Ursprünge und verwenden Sie nicht Access-Control-Allow-Origin: *.
1async function fetchCrossOriginData() {
2 // Example: cross-origin fetch sending cookies.
3 // Server must set Access-Control-Allow-Credentials: true
4 // and a specific trusted origin.
5 const res = await fetch('https://api.example.com/data', {
6 credentials: 'include', // send cookies only to trusted domains
7 method: 'GET'
8 });
9 return res;
10}- Die Kombination aus CORS und Cookies ist aus Sicherheitsperspektive sehr heikel. Verwalten Sie erlaubte Ursprünge strikt mit einer Whitelist und vermeiden Sie unnötige Cross-Site-Kommunikation. Erzwingen Sie außerdem bei Verwendung von
SameSite=None; SecureHTTPS, um Man-in-the-Middle-Angriffe zu verhindern.
Beispiel: Sichere Session-Cookie-Einstellungen mit Express (TypeScript)
In der Praxis verwenden Sie Express, die Bibliothek cookie, express-session usw. Unten ein einfaches Beispiel mit express und cookie-parser. In der Praxis setzen Sie secure auf true und verwalten das secret über Umgebungsvariablen.
1// Express example using cookie-parser and setting a secure httpOnly cookie.
2// npm install express cookie-parser @types/express @types/cookie-parser
3import express from 'express';
4import cookieParser from 'cookie-parser';
5
6const app = express();
7app.use(cookieParser(process.env.COOKIE_SECRET));
8
9app.post('/login', (req, res) => {
10 // authenticate user (omitted)
11 const sessionId = 'generated-session-id';
12 res.cookie('sid', sessionId, {
13 httpOnly: true,
14 secure: true, // require HTTPS in production
15 sameSite: 'lax',
16 maxAge: 1000 * 60 * 60 // 1 hour
17 });
18 res.json({ ok: true });
19});
20
21app.listen(3000);- Mit der
secret-Funktion voncookieParserkönnen Sie einfach mit signierten Cookies arbeiten. In realen Anwendungen sollten Sie aus Sicherheits- und Skalierbarkeitsgründen keine Daten direkt in Cookies speichern; verwenden Sie stattdessen einen dedizierten Session-Store.
Cookie-Präfixe __Host- und __Secure-
Browser erzwingen besondere Regeln für bestimmte Präfixe.
- Das Präfix
__Secure-Beginnt ein Cookie-Name mit__Secure-, ist das AttributSecureerforderlich. - Das Präfix
__Host-Beginnt er mit__Host-, istSecureerforderlich, der Pfad muss/(Root) sein undDomaindarf nicht gesetzt werden.
Die Verwendung dieser Präfixe reduziert Fehlkonfigurationen und verbessert die Sicherheit.
Cookie-Best Practices
Um Cookies sicher zu handhaben, beachten Sie die folgenden Punkte.
- Speichern Sie keine sensiblen Informationen direkt in Cookies. Bevorzugen Sie für Zugriffstoken eine serverseitige Sitzungs-ID.
- Setzen Sie Session-Cookies mit
HttpOnly,SecureundSameSite=Lax(oder Strict). - Nutzen Sie Präfixe wie
__Host-und__Secure-. - Erwägen Sie Signaturen (HMAC) und Verschlüsselung, um Manipulation und Abhören zu verhindern.
- Aktivieren Sie
Secureund erzwingen Sie HTTPS. - Streben Sie minimale Berechtigungen und kurze Ablaufzeiten an.
- Verwenden Sie CSRF-Token.
- Achten Sie auf Unterschiede im
SameSite-Verhalten zwischen Browsern, insbesondere älteren.
Häufige Missverständnisse über Cookies
Bezüglich Cookies sollten Sie die folgenden verbreiteten Irrtümer beachten.
- 'Das Hinzufügen von
HttpOnlybeseitigt die Auswirkungen von XSS.' Zwar verhindertHttpOnlyden Zugriff auf Cookies aus JavaScript, dennoch kann XSS weiterhin genutzt werden, um beliebige Anfragen abzusetzen. Sie sollten außerdem CSRF-Token-Überprüfung, CSP (Content Security Policy) und Eingabebereinigung einsetzen. - '
Secureist für die lokale Entwicklung unnötig.' Das Simulieren von HTTPS und die Überprüfung des Verhaltens auch in lokalen Umgebungen verbessert die Testgenauigkeit. Mindestens in Staging- und Produktionsumgebungen sollte HTTPS verwendet werden. - 'Lange Ablaufzeiten sind praktisch.' Wenn Sie lange Cookie-Lebensdauern festlegen, verlängert sich der Zeitraum, in dem sie bei Diebstahl missbraucht werden können. Sie können kürzere Ablaufzeiten festlegen und regelmäßige Re-Authentifizierung sowie Token-Rotation einführen.
Zusammenfassung
Obwohl Cookies leicht zu verwenden sind, kann eine falsche Handhabung Sicherheitslücken einführen. Um sie mit TypeScript korrekt zu verwalten, ist es wichtig, Attribute wie HttpOnly, Secure und SameSite zu verstehen und sichere serverseitige Einstellungen durchzusetzen. Indem Sie keine sensiblen Daten direkt speichern und Signaturen mit kurzen Ablaufzeiten kombinieren, erreichen Sie ein sicheres und zuverlässiges Sitzungsmanagement.
Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.