JWT: privat og offentlig nøgle (RS256)

Denne side er til undervisning: du ser både hvordan en JWT er bygget, og hvordan man beviser at den er udstedt af den rigtige auth-server — uden at dele den hemmelige private nøgle med apps eller browsere.

1. Tre dele: læsbart indhold + kryptografisk bevis

En JWT er tre Base64URL-dele adskilt af punktum. De to første kan alle dekode (det er ikke kryptering — kun kodning). Den tredje del er signaturen: et matematisk bevis lavet med serverens private nøgle.

header
algoritme, kid
· payload
claims: sub, iss, aud, exp …
· signatur
bevis for header+payload

Vigtigt: At kunne læse payload betyder ikke at du stoler på den. Først efter signatur-check + issuer/audience/livstid er claims “officielle”.

Asymmetrisk (RSA): Kun auth-serveren har privat nøgle til at signere. Alle andre bruger den offentlige nøgle (offentliggjort via JWKS) til at tjekke signaturen. Den offentlige nøgle kan ikke bruges til at forfalske nye gyldige signaturer.

2. Overblik: udstedelse vs. verifikation

Serveren signerer med privat nøgle. Enhver klient henter den matchende offentlige nøgle og verificerer.

flowchart LR subgraph S["Auth-server"] direction TB SK["Privat RSA-nøgle (hemmelig)"] SK --> SIGN["RS256-signering af header.payload"] end subgraph J["JWT til klient"] HP["header.payload (alle kan læse)"] SIG["signatur"] end SIGN --> SIG HP --- SIG subgraph K["Klient: browser eller API"] direction TB JW["GET /.well-known/jwks.json"] JW --> PUB["Offentlig nøgle: n, e, kid"] PUB --> V["Verificér RS256"] HP --> V SIG --> V end

3. Flow: sådan verificerer du en JWT (undervisningstrin)

Følg rækkefølgen når du bygger login i en app eller validerer Authorization: Bearer på et API.

flowchart TD A["1. Modtag JWT"] --> B["2. Dekodér header og payload (Base64URL → JSON, stadig uden tillid)"] B --> C["3. Læs kid i header"] C --> D["4. Hent JWKS fra issuer"] D --> E["5. Vælg JWK med samme kid"] E --> F["6. Verificér RS256-signatur"] F --> G{"7. Tjek iss, aud, exp, nbf"} G -->|"Alle OK"| H["Godkend"] G -->|"Ellers"| X["Afvis"] H --> Y["8. Først nu: stol på sub, roller, email …"]

Hvorfor kid?

Nøgler roteres nogle gange. JWKS kan indeholde flere nøgler. kid i JWT-headeren fortæller hvilken offentlig nøgle der passede til denne signatur.

Hvorfor iss og aud?

4. JWKS-URL i denne demo

Nedenfor er den konkrete adresse der bruges sammen med shared-config.js (authBaseUrl). Samme endpoint bruger Mercantec Auth til at udstille den offentlige nøgle der matcher den private signeringsnøgle.

(indlæses …)

5. Dit access token (live)

Header

—

Payload (claims)

email vises maskeret (**@domæne) — lokale dele skjules i demo.

—

Nedenfor: signatur tjekkes med biblioteket jose mod GET /.well-known/jwks.json — samme princip som i produktion.

Demo ved MAGS (underviser) — ikke Mercantecs officielle produkt. [email protected]