`Cookie` i TypeScript
Denne artikkelen forklarer Cookie i TypeScript.
Vi går gjennom praktiske mønstre for å håndtere informasjonskapsler trygt og pålitelig både i nettleseren og på serveren.
YouTube Video
Cookie i TypeScript
Grunnleggende konsepter for informasjonskapsler
En informasjonskapsel er en mekanisme for å lagre små tekststrenger (navn=verdi-par) på klienten, opprettet via HTTP-headeren Set-Cookie eller document.cookie. Du kan styre oppførselen deres med sikkerhetsattributter (HttpOnly, Secure, SameSite, osv.).
Grunnleggende operasjoner i nettleseren: document.cookie
Nedenfor er et minimalt eksempel på å skrive en informasjonskapsel i nettleseren. Opprett en informasjonskapsel ved å legge til en streng til document.cookie.
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');- Denne koden oppretter en informasjonskapsel som utløper om 7 dager. Det er lett å bruke på nettlesersiden, men siden du ikke kan sette
HttpOnly, bør du unngå å lagre sensitiv informasjon.
Lese informasjonskapsler (nettleser)
Følgende funksjon er en hjelpefunksjon som henter verdien av cookien med et angitt navn fra document.cookie. document.cookie returneres som en streng skilt med semikolon og et mellomrom ('; '). Derfor deler vi den opp og leter etter den ønskede cookien.
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);- Denne funksjonen dekoder både cookienavnet og verdien for å sammenligne og hente dem på en sikker måte. Den håndterer dupliserte cookienavn og kodede spesialtegn, noe som gjør den til en enkel, men robust implementasjon.
Forstå og bruk sikre attributter
Informasjonskapsler har flere viktige attributter som hver styrer sikkerheten og virkeområdet for oppførsel.
HttpOnly-attributtet hindrer at informasjonskapselen er tilgjengelig fra JavaScript, og bidrar til å redusere XSS-angrep (skripting på tvers av nettsteder). Merk at du ikke kan setteHttpOnlyfra nettlesersiden.Secure-attributtet begrenser informasjonskapsler til kun å bli sendt over HTTPS, noe som reduserer risikoen for avlytting og manipulering.SameSite-attributtet styrer om informasjonskapsler sendes med forespørsler på tvers av nettsteder, og bidrar til å forhindre CSRF-angrep (forfalskning av forespørsler på tvers av nettsteder).Path-attributtet angir omfanget av forespørselsstier som informasjonskapselen sendes for, ogDomain-attributtet angir domenet der informasjonskapselen er gyldig.- Ved å sette
Expires- ellerMax-Age-attributtet kan du kontrollere informasjonskapselens utløpstid.
Eksempel på å legge til SameSite / Secure i nettleseren (det som er mulig)
HttpOnly kan ikke settes på klientsiden. Nedenfor er et eksempel på å legge til SameSite og Secure på klientsiden. Imidlertid har Secure bare effekt på HTTPS-sider.
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=Laxer et trygt og vanlig valg. For sterkere begrensninger brukSameSite=Strict, men legitime navigeringer fra eksterne nettsteder kan slutte å fungere.
Sette informasjonskapsler på serveren (Set-Cookie) (Node / TypeScript)
På serveren kan du legge til HttpOnly via Set-Cookie-headeren, så sesjonshåndtering bør ideelt gjøres på serversiden. Nedenfor er et eksempel som bruker 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});- Når du setter
HttpOnly-attributtet på serversiden, blir informasjonskapselen utilgjengelig fra JavaScript, noe som gjør det vanskeligere for XSS-angrep (skripting på tvers av nettsteder) å stjele den. I tillegg kan du ved å legge tilSecure-attributtet slik at informasjonskapsler alltid sendes over HTTPS, forhindre avlytting og manipulering og forbedre kommunikasjonssikkerheten.
Implementasjon for serialisering/parsing av informasjonskapsler (en hjelpefunksjon på serversiden)
Nedenfor er et enkelt verktøy på serversiden som bygger en Set-Cookie-topptekststreng.
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"
- Dette verktøyet danner grunnlaget for å opprette
Set-Cookiepå en egendefinert server. Biblioteker kan håndtere mange flere kanttilfeller.
Hindre manipulering med signaturer (HMAC)
Det er farlig å lagre viktige verdier direkte i informasjonskapsler. Vi introduserer en metode som signerer verdier på serveren for å oppdage manipulering. Her bruker vi HMAC-SHA256. I produksjon må du også håndtere tilbakekalling av tokens på serversiden.
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"
- Med denne metoden kan du sjekke om Cookie-verdien har blitt manipulert. Ikke inkluder signeringsnøkkelen i kildekoden; håndter den via sikre mekanismer som miljøvariabler.
Informasjonskapsler og CSRF-mottiltak (generelle mønstre)
Økter som bruker informasjonskapsler trenger CSRF-beskyttelse. Typiske mottiltak inkluderer:.
- Sett
SameSitetilLaxellerStrictfor å forhindre unødvendig sending på tvers av nettsteder. BrukSameSite=None; Securebare når kommunikasjon på tvers av opprinnelser er nødvendig. - Bruk CSRF-tokens, validert av serveren, for skjemaer og API-forespørsler. Ikke lagre tokenet i en
HttpOnly-cookie; gi det i stedet via responskroppen eller metatagger, og la JavaScript lese det bare når det er nødvendig. - Hvis tokenet kan nås fra JavaScript, sørg også for å implementere XSS-beskyttelser (CSP, utdata-escaping osv.).
- Krev reautentisering for sensitive handlinger og ved innlogging, og hindre øktfikseringsangrep.
Nedenfor er et sikkert klienteksempel som sender CSRF-tokenet i en header. Dette forutsetter at klienten allerede har mottatt tokenet fra serveren, f.eks. i responskroppen.
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}- Hvis du angir
credentials: 'same-origin', sendes bare cookies fra samme opprinnelse. På serveren, valider verdien avX-CSRF-Token-headeren og verifiser at tokenet samsvarer. Hvis forespørsler på tvers av nettsteder er nødvendige, konfigurer CORS nøye.
På tvers av nettsteder (CORS) og forholdet til credentials
For å sende og motta cookies i kommunikasjon på tvers av opprinnelser, må klienten angi credentials: 'include' og serveren må sette Access-Control-Allow-Credentials: true. Begrens imidlertid denne konfigurasjonen til klarerte opprinnelser, og ikke bruk 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}- Kombinasjonen av CORS og cookies er svært delikat fra et sikkerhetsperspektiv. Administrer tillatte opprinnelser strengt med en hvitliste, og unngå unødvendig kommunikasjon på tvers av nettsteder. I tillegg, når du bruker
SameSite=None; Secure, håndhev HTTPS for å forhindre man-in-the-middle-angrep.
Eksempel: sikre innstillinger for sesjonsinformasjonskapsler med Express (TypeScript)
I praksis bruk Express, biblioteket cookie, express-session og så videre. Nedenfor er et enkelt eksempel med express og cookie-parser. I praksis, sett secure til true og håndter secret via miljøvariabler.
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);- Ved å bruke funksjonen
secreticookieParserkan du enkelt arbeide med signerte cookies. I virkelige applikasjoner bør du imidlertid, av hensyn til sikkerhet og skalerbarhet, ikke lagre data direkte i cookies; bruk i stedet et dedikert sesjonslager.
Informasjonskapsel-prefiksene __Host- og __Secure-
Nettlesere håndhever spesielle regler for visse prefikser.
- Prefikset
__Secure-Hvis navnet på en informasjonskapsel starter med__Secure-, kreves attributtetSecure. - Prefikset
__Host-Hvis navnet starter med__Host-, erSecurepåkrevd, banen må være/(rot), ogDomainmå ikke settes.
Å bruke disse reduserer feilkonfigurasjon og forbedrer sikkerheten.
Beste praksis for informasjonskapsler
For å håndtere Cookies sikkert, vurder følgende punkter.
- Ikke lagre sensitiv informasjon direkte i informasjonskapsler. Foretrekk en sesjons-ID på serversiden for tilgangstoken.
- Sett sesjonsinformasjonskapsler med
HttpOnly,SecureogSameSite=Lax(eller Strict). - Bruk prefikser som
__Host-og__Secure-. - Vurder signaturer (HMAC) og kryptering for å forhindre manipulering og avlytting.
- Aktiver
Secureog krev HTTPS. - Sikt på minst mulig privilegier og korte utløpstider.
- Bruk CSRF-tokener.
- Vær oppmerksom på forskjeller i
SameSite-atferd mellom nettlesere, spesielt eldre.
Vanlige misoppfatninger om informasjonskapsler
Når det gjelder informasjonskapsler, vær oppmerksom på følgende vanlige misoppfatninger.
- 'Å legge til
HttpOnlyfjerner effekten av XSS.' Selv omHttpOnlyhindrer JavaScript i å få tilgang til informasjonskapsler, kan XSS fortsatt brukes til å sende vilkårlige forespørsler. Du bør også bruke CSRF-tokenverifisering, CSP (Content Security Policy) og sanitering av inndata. - '
Secureer unødvendig for lokal utvikling.' Å simulere HTTPS og verifisere oppførsel også i lokale miljøer forbedrer testnøyaktigheten. Som et minimum bør HTTPS brukes i staging- og produksjonsmiljøer. - 'Lange utløpstider er praktiske.' Hvis du angir lange levetider for informasjonskapsler, øker perioden de kan misbrukes dersom de blir stjålet. Du kan sette kortere utløpstider og innføre periodisk reautentisering og token-rotasjon.
Sammendrag
Selv om informasjonskapsler er lette å bruke, kan feilaktig håndtering introdusere sikkerhetssårbarheter. For å håndtere dem riktig med TypeScript er det viktig å forstå attributter som HttpOnly, Secure og SameSite, og håndheve sikre innstillinger på serversiden. Ved å ikke lagre sensitiv data direkte og kombinere signaturer med korte utløpstider kan du oppnå trygg og pålitelig sesjonshåndtering.
Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.