AngularAtlasAusg. 22.2

Kap. 17Sicherheit & Globalisierung74 / 75

OAuth 2.1 & OpenID Connect mit PKCE

Der Authorization-Code-Flow mit PKCE Schritt für Schritt: Verifier und Challenge, State und Nonce, das ID-Token und warum ein BFF sicherer ist.

Architektur ~0 Min. Lesezeit

Bei der Anmeldung mit Google, Microsoft, Keycloak oder Auth0 sieht deine App das Passwort nie. Sie schickt den Nutzer zum Identitätsanbieter, der ihn mit einem einmaligen Code zurückschickt; die App tauscht diesen Code gegen Tokens. OAuth 2.1 — die aufgeräumte Version von OAuth 2.0 — behält für Apps im Browser einen einzigen Flow: den Authorization Code mit PKCE.

PKCE (Proof Key for Code Exchange, ausgesprochen „pixy“) löst ein präzises Problem. Eine Single-Page-App ist ein öffentlicher Client: Sie hat kein Geheimnis, das sie verstecken könnte, denn alles, was sie ausliefert, kann gelesen werden. Also braucht sie einen anderen Weg, zu beweisen, dass derjenige, der den Code einlöst, derselbe ist, der ihn angefordert hat. Die Demos auf dieser Seite verwenden echte Kryptografie (Web Crypto), keine Nachahmung.

Falls du noch den Implicit Flow nutzt
Der Implicit Flow (response_type=token, Tokens im URL-Fragment) ist aus OAuth 2.1 verschwunden: Tokens in URLs landen im Browserverlauf, in Logs und in Referer-Headern. Der Umstieg auf den Code Flow mit PKCE ist meist eine Konfigurationsänderung in deiner Bibliothek und beim Anbieter.

Der Flow in sieben Schritten

Die App bereitet ein paar Zufallswerte vor, schickt den Browser zum Anbieter, bekommt einen Code zurück und tauscht ihn — zusammen mit einem Beweis — gegen Tokens. Erst der letzte Schritt betrifft deine API. Geh ihn in der Demo durch; hake „Angreifer“ an, um zu sehen, was die Prüfung von state verhindert.

app (browser)                         Identitätsanbieter                     API
  │ 1. verifier, challenge = S256(verifier), state, nonce                     │
  │ 2. GET /authorize?…&code_challenge&state&nonce ─▶│                         │
  │                                  3. Login, MFA, Einwilligung               │
  │◀─ 4. 302 /callback?code=…&state=…  (state prüfen!)                         │
  │ 5. POST /token  code + code_verifier ────────────▶│ S256(verifier) == challenge?
  │◀─ 6. access_token, id_token, refresh_token ───────│                         │
  │ 7. GET /orders  Authorization: Bearer <access_token> ─────────────────────▶│
LiveAuthorization Code mit PKCE, Schritt für Schritt
1verifier, challenge, state, nonce
2GET /authorize
3Login, MFA, Einwilligung
4302 /callback?code&state
5POST /token + verifier
6Access-, ID-, Refresh-Token
7GET /api … Bearer
Drücke „Weiter“ durch alle sieben Schritte. Hake dann „Gefälschter Callback“ an und fang neu an: Der Flow stoppt bei Schritt 4.

PKCE: beweisen, dass du gefragt hast

Vor dem Redirect erzeugt die App einen zufälligen code_verifier und schickt nur dessen Hash, die code_challenge, an /authorize. Der Anbieter merkt ihn sich neben dem Code. Wenn die App den Code bei /token einlöst, schickt sie den Verifier selbst; der Anbieter hasht ihn und vergleicht. Wer den Code abfängt — eine bösartige App mit demselben Redirect, ein Log, eine Browser-Erweiterung —, hat den Verifier nicht, und der Code ist für ihn wertlos.

/** base64url ohne Padding (RFC 4648 §5), wie PKCE es verlangt */
function base64url(bytes: Uint8Array): string {
  let binary = '';
  for (const b of bytes) binary += String.fromCharCode(b);
  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

/** 32 Zufallsbytes → 43 Zeichen (erlaubt sind mindestens 43, höchstens 128) */
export function createVerifier(): string {
  return base64url(crypto.getRandomValues(new Uint8Array(32)));
}

/** code_challenge = BASE64URL(SHA-256(code_verifier)), Methode S256 */
export async function challengeFor(verifier: string): Promise<string> {
  const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
  return base64url(new Uint8Array(digest));
}

// RFC 7636, Anhang B:
// challengeFor('dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
//   → 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'
LiveVerifier, Challenge und die Prüfung bei /token
  1. 1Die App erzeugt einen Verifier

    0 Zeichen · erlaubt sind 43 bis 128

    code_challenge…
  2. 2Nur die Challenge geht an /authorize

    Der Anbieter hat noch nichts erhalten.

  3. 3Den Code bei /token einlösen
Erzeuge einen Verifier, sende die Challenge und löse den Code dann auf beide Arten ein. Lade das Beispiel aus RFC 7636, um die Implementierung gegen den Standard zu prüfen.

Verwende S256, nie plain (bei plain ist die Challenge der Verifier, wer den Redirect sieht, hat also alles). Der Verifier bleibt in sessionStorage — nur dieser Tab — und wird gelöscht, sobald der Code getauscht ist.

state, nonce und redirect_uri

  • state — ein Zufallswert, vor dem Redirect gespeichert und in /callback geprüft. Ohne ihn kann ein Angreifer das Opfer mit dem Code des Angreifers zu deinem Callback schicken, und das Opfer ist am Ende im Konto des Angreifers angemeldet (Login-CSRF). PKCE blockiert das auch, aber Anbieter verlangen state trotzdem, und du brauchst ihn ohnehin, um deinen eigenen Kontext mitzunehmen.
  • nonce — ein Zufallswert, an /authorize geschickt, der im ID-Token zurückkommen muss. Er beweist, dass das ID-Token für diesen Login ausgestellt und nicht von einem früheren kopiert wurde.
  • redirect_uri — beim Anbieter exakt registriert, ohne Wildcards. Und wohin es nach dem Login geht (returnTo), speichert deine App vor dem Redirect; nimm es nie aus einem ?returnUrl= in der Adresszeile, sonst wird deine Login-Seite zum Open Redirect.
import { challengeFor, createVerifier } from './pkce';

const AUTHORIZE = 'https://id.example.com/authorize';

export async function login(returnTo = '/'): Promise<void> {
  const verifier = createVerifier();
  const state = createVerifier(); // zufällig, nur einmal verwendbar
  const nonce = createVerifier();

  // sessionStorage: nur dieser Tab, weg, wenn der Tab geschlossen wird
  sessionStorage.setItem('oauth', JSON.stringify({ verifier, state, nonce, returnTo }));

  const url = new URL(AUTHORIZE);
  url.search = new URLSearchParams({
    response_type: 'code',
    client_id: 'atlas-spa',
    redirect_uri: `${location.origin}/callback`, // GENAU so registriert, keine Wildcards
    scope: 'openid profile email',
    code_challenge: await challengeFor(verifier),
    code_challenge_method: 'S256',
    state,
    nonce,
  }).toString();
  location.assign(url);
}

Drei Tokens, drei Aufgaben

Die Antwort von /token enthält bis zu drei Tokens, und sie zu verwechseln ist der häufigste Fehler. Das ID-Token sagt der App, wer sich angemeldet hat. Das Access-Token sagt der API, was der Aufrufer darf. Das Refresh-Token holt neue Access-Tokens ohne neuen Login. Ein JWT im Browser zu dekodieren ist für die Anzeige nützlich, aber keine Validierung: Die Signatur wird mit den öffentlichen Schlüsseln des Anbieters (JWKS) geprüft, und das ist Arbeit für eine Bibliothek.

ID tokenAccess tokenRefresh token
Gelesen vondeiner Appdeiner APIdem Anbieter
Gesendet annirgendwohin — es bleibt in der Appnur den Origin deiner APInur /token des Anbieters
LebtMinuten5–60 MinutenStunden bis Tage, bei jeder Nutzung rotiert

Sicherer: ein BFF behält die Tokens

Nach Schritt 6 liegen die Tokens im Browser — genau dort, wo ein XSS sie erreichen kann. Das IETF-Dokument zu OAuth für browserbasierte Apps beschreibt eine stärkere Option: ein Backend for Frontend. Ein kleiner Server auf deiner eigenen Site führt den Code-Tausch durch, hält die Tokens serverseitig und gibt dem Browser nur ein HttpOnly-Session-Cookie, das JavaScript nicht lesen kann.

browser (SPA)                BFF (dein Server, gleiche Site)            Identitätsanbieter
  │ GET /auth/login ──────────▶│ PKCE + state + nonce, auf dem Server ──────▶│ /authorize
  │◀─ 302 zum Anbieter ────────│                                             │
  │                    …Login beim Anbieter, Redirect zurück zum BFF…        │
  │                            │ code + verifier ──────────────────────────▶│ /token
  │                            │◀── access, id, refresh (bleiben HIER) ──────│
  │◀─ Set-Cookie: session=…; HttpOnly; Secure; SameSite=Strict               │
  │ GET /api/orders (cookie) ─▶│ setzt Authorization: Bearer … ──▶ API       │

Die SPA ruft /api auf ihrem eigenen Origin auf; das BFF fügt das Access-Token hinzu und kümmert sich um den Refresh. Ein XSS kann weiterhin Anfragen stellen, solange die Seite offen ist, aber keine Tokens stehlen, um sie anderswo zu nutzen. Der Preis: eine Komponente mehr im Betrieb und CSRF-Schutz für das Cookie (SameSite, ein Anti-CSRF-Header). Für Tokens im Browser steht der Interceptor mit Warteschlange und Refresh auf der Seite zu Tokens und Refresh.

In Angular: eine Bibliothek, ein Guard und ein Interceptor

Implementiere das Protokoll nicht selbst. Zertifizierte Bibliotheken wie angular-auth-oidc-client oder angular-oauth2-oidc übernehmen Discovery des Anbieters, PKCE, Validierung des ID-Tokens samt Signatur, Refresh und Logout. Der Code auf dieser Seite zeigt, was sie tun, damit du sie mit offenen Augen konfigurieren und debuggen kannst. Dein Teil:

  • Konfiguration: Authority, Client-ID, redirect_uri, Scopes und der Code Flow mit PKCE — meist der Standard.
  • Ein Guard auf den privaten Routen, der den Login startet und sich merkt, wohin es zurückgeht. Siehe Guards & Resolver.
  • Ein Interceptor, der das Access-Token nur für den Origin deiner API hinzufügt. Ein Token, das an jede URL geht, landet bei Dritten; siehe Sicherheit für den Rest des Bildes.

Wann ja, wann nein

OAuth / OIDC
  • Login über einen externen Identitätsanbieter: Firmen-SSO, Google, Microsoft, Apple.
  • Mehrere Apps, die denselben Login und dieselben Nutzer teilen.
  • MFA, Passkeys und Kontowiederherstellung, die du lieber Spezialisten überlässt.
Etwas Einfacheres
  • Eine einzelne App mit eigenen Nutzern und eigenem Backend: Ein klassisches Session-Cookie kann alles sein, was du brauchst. Tokens und Refresh haben eine eigene Seite.
  • Server-zu-Server-Aufrufe: Das ist der Client-Credentials-Flow, auf dem Server, nie im Browser.
  • Das Protokoll in Produktion selbst schreiben: Nimm eine zertifizierte Bibliothek.

Häufige Stolperfallen

  • Der Implicit Flow oder Tokens in der URL. Sie landen im Verlauf, in Logs und im Referer-Header.
  • state nicht prüfen. Der Callback akzeptiert einen Code, den deine App nie angefordert hat.
  • Das ID-Token an die API geschickt. Es ist für die App; die API nimmt Access-Tokens mit der richtigen Audience.
  • Dekodieren statt validieren. Ohne Signaturprüfung kann jeder ein JWT mit beliebigen Claims schreiben.
  • Der Verifier in localStorage, nach Gebrauch behalten. Er gehört in sessionStorage und stirbt mit dem Tausch.
  • ?returnUrl= aus der Adresszeile. Deine Login-Seite wird zum Open Redirect für Phishing.

Spickzettel

Browser-Apps (OAuth 2.1)  Authorization Code + PKCE, sonst nichts (kein Implicit Flow)
code_verifier             43–128 Zufallszeichen, in sessionStorage, nach Gebrauch gelöscht
code_challenge            BASE64URL(SHA-256(verifier)), Methode S256 (nie "plain")
state                     zufällig, auf /callback geprüft: stoppt Login-CSRF
nonce                     zufällig, muss im ID-Token stehen: stoppt wiederverwendete Tokens
redirect_uri              exakt registriert, keine Wildcards; returnTo VOR dem Redirect gespeichert
ID-Token                  wer sich angemeldet hat (für die App); iss, aud, exp, nonce, Signatur prüfen
Access-Token              was du aufrufen darfst (für die API); nur an den Origin deiner API
Refresh-Token             bei jeder Nutzung rotiert oder gar nicht im Browser
am sichersten             ein BFF: Tokens auf dem Server, ein HttpOnly-Cookie im Browser
Logout                    lokale Session + end_session_endpoint des Anbieters
nicht selbst schreiben    zertifizierte Bibliotheken: angular-auth-oidc-client, angular-oauth2-oidc

Kap. 17 · 0 von 4 abgeschlossen

Lektion abgeschlossen?

Markiere sie, dann erscheint sie auf deiner Karte: im Inhaltsverzeichnis und auf der Startseite.

Wird automatisch markiert, sobald du die ganze Lektion gelesen hast.

  1. Sicherheit: XSS, Sanitizing & CSP
  2. Authentifizierung: Tokens & Refresh
  3. OAuth 2.1 & OpenID Connect mit PKCE
  4. Internationalisierung (i18n)
Deine ganze Karte ansehen

Alle 75 Seiten · tippen zum Filtern

  • 01Was ist neu in Angular 21 & 22Alle wichtigen Änderungen in v21 und v22 in Kürze, mit Link zur Seite, die sie jeweils erklärt.Start
  • 01Deine erste App, Schritt für SchrittEine Leseliste, von einer leeren Komponente bis zur fertigen App — Signals, @for, Inputs und Outputs, ein Service und ein Formular, Schritt für Schritt.Start
  • 01Schnelle Entscheidungen„Wohin damit?“, „Signal oder Observable?“, „Shared oder Feature?“ — kurze Antworten auf Alltagsfragen.Start
  • 01Angular-Interviewfragen60 echte Interviewfragen für Junior, Mid und Senior, mit der passenden Antwort, der Nachfrage und den Warnsignalen. Dazu ein Probeinterview.Start
  • 02Standalone & BootstrapWie eine App ohne NgModule startet: bootstrapApplication, app.config.ts, imports in der Komponente.Moderne Grundlagen
  • 02Data Binding & EventsInterpolation, Property- und Attribut-Bindings, Events mit $event und Tastenfiltern und wie [( )] aufgebaut ist — was in das DOM geht und was zurückkommt.Moderne Grundlagen
  • 02Control Flow: @if, @for, @switchDie Block-Syntax, die *ngIf/*ngFor/ngSwitch ersetzt, mit track, @empty und Exhaustive Checks.Moderne Grundlagen
  • 02@let und die neuen Template-AusdrückeLokale Variablen mit @let, Arrow Functions, Spread, Regex, instanceof, Kommentare in Tags.Moderne Grundlagen
  • 02@defer — Lazy Loading in TemplatesSchwere Komponenten nur laden, wenn sie gebraucht werden: Trigger, Prefetch, Placeholder, Loading, Error.Moderne Grundlagen
  • 02Class- & Style-BindingsWarum [class.x] und [style.x] ngClass und ngStyle abgelöst haben (mit automatischer Migration ab v21).Moderne Grundlagen
  • 02Komponenten-Styles & Kapselung:host, die drei Kapselungsmodi, Theming mit CSS-Variablen und warum ::ng-deep der letzte Ausweg ist.Moderne Grundlagen
  • 02Pipes: wann und wiePure vs. Impure Pipes, eigene Pipes und wie du zwischen Pipe, computed() und Methode wählst.Moderne Grundlagen
  • 03signal() und computed()Die reaktiven Grundbausteine: beschreibbarer Zustand, abgeleiteter Zustand, Gleichheit, untracked und Regeln zur Immutability.Signals & Reaktivität
  • 03effect() — wann ja, wann neinMit Signals synchronisierte Seiteneffekte: localStorage, Logging, imperative APIs. Und ihre Stolperfallen.Signals & Reaktivität
  • 03linkedSignal() — editierbarer abgeleiteter ZustandEin Signal, das sich zurücksetzt, wenn sich seine Quelle ändert, das du aber auch manuell setzen kannst.Signals & Reaktivität
  • 03resource, rxResource, httpResourceAsynchrone Daten als Signals: status, value, error, reload, automatischer Abbruch. Stabil seit v22.Signals & Reaktivität
  • 03debounced() — verzögerte SignalsDie „Debounce“-Variante eines Signals, ohne RxJS. Perfekt für die Suche.Signals & Reaktivität
  • 03Listen: suchen, filtern, sortieren, blätternEine Kette von computed-Signals, die nur neu berechnet, was sich geändert hat — mit den Filtern in der URL, damit ein Link dieselbe Ansicht öffnet.Signals & Reaktivität
  • 03Observables von null anWas ein Observable ist, subscribe und unsubscribe, die Operatoren, die du jede Woche brauchst, cold vs. hot — und wann ein Signal reicht.Signals & Reaktivität
  • 03Signals ↔ RxJStoSignal, toObservable, takeUntilDestroyed, outputFromObservable — und wann RxJS weiterhin die richtige Wahl bleibt.Signals & Reaktivität
  • 04input() und output()Inputs als Signals (required, transform, alias) und typisierte Outputs. Daten nach unten, Events nach oben.Komponenten: Kommunikation
  • 04model() — Two-Way-BindingBanana-in-a-Box [( )] mit einer einzigen API. Wann du es nutzt und wann input + output besser ist.Komponenten: Kommunikation
  • 04viewChild & contentChildQueries als Signals: viewChild, viewChildren, contentChild, contentChildren, die Option read.Komponenten: Kommunikation
  • 04Lifecycle & DestroyRefWelche Hooks in der Signals-Ära noch zählen, afterNextRender, DestroyRef und typisiertes ngOnChanges.Komponenten: Kommunikation
  • 04Content Projectionng-content mit select, mehrere Slots, Standardinhalt und die Falle der bedingten Projektion.Komponenten: Kommunikation
  • 04ng-template & ngTemplateOutletTemplates als Werte: Render Props in Angular, typisierter Kontext und Anpassen von Komponenten.Komponenten: Kommunikation
  • 05Smart vs. DumbContainer vs. Presentational: wer den Zustand hält, wer nur anzeigt und wie du die beiden sauber trennst.Komponenten-Design
  • 05Generische Komponenten <T>Eine korrekt typisierte DataTable<T> oder Select<T>, mit Templates für Zellen.Komponenten-Design
  • 05Dynamische KomponentenNgComponentOutlet, createComponent mit inputBinding/outputBinding und ein Dashboard, das aus einer Konfiguration gebaut wird.Komponenten-Design
  • 05Direktiven & Host-KompositionAttribut-Direktiven, die host: {}-Metadaten und die Directive Composition API (hostDirectives).Komponenten-Design
  • 05Eigene Formular-ControlsFormValueControl (Signal Forms) vs. ControlValueAccessor: eine Sternebewertung, in beiden Varianten.Komponenten-Design
  • 05Change DetectionOnPush ist ab v22 der Standard, zone.js entfällt ab v21. Was das Rendering auslöst und wie du dir nicht die Finger verbrennst.Komponenten-Design
  • 06inject() & @Service()Der neue @Service()-Decorator ab v22, inject() vs. Konstruktor und der Injection-Kontext.Dependency Injection
  • 06Provider & die Injector-HierarchieRoot vs. Route vs. Komponente, useClass/useValue/useFactory/useExisting und die Modifier optional/self/skipSelf.Dependency Injection
  • 06InjectionToken & provideX()Typisierte Konfiguration, provideFeature()-Funktionen, makeEnvironmentProviders und Initializer.Dependency Injection
  • 06injectAsync() — Lazy ServicesLade einen schweren Service erst, wenn du ihn brauchst, mit Prefetch im Leerlauf.Dependency Injection
  • 07Ordnerstrukturcore / shared / features, was in welchen Ordner gehört und wie ein Feature von innen aussieht.Architektur der Anwendung
  • 07Shared vs. FeatureWann du eine Komponente nach Shared verschiebst und (vor allem) wann NICHT. Eine konkrete Checkliste.Architektur der Anwendung
  • 07Interfaces & ModelleInline-Interface oder eigene Datei? DTO vs. Domänenmodell, type vs. interface, wohin damit.Architektur der Anwendung
  • 07State Management mit SignalsEinfache Signal-Stores, Fassaden, lokaler vs. globaler Zustand und wann du NgRx brauchst.Architektur der Anwendung
  • 07Styleguide & NamensgebungDie aktuellen offiziellen Konventionen: Dateinamen ohne Suffixe, protected, readonly, Reihenfolge der Member.Architektur der Anwendung
  • 07Barrels, Aliase & Grenzenindex.ts, Pfad-Aliase, die öffentliche API eines Features und Abhängigkeitsregeln, die sich automatisch prüfen lassen.Architektur der Anwendung
  • 07Fehler: @boundary & ErrorHandlerDer neue @boundary-Block ab v22.2, der globale ErrorHandler, HTTP-Fehler und Fehler aus resource.Architektur der Anwendung
  • 08Modernes Routing & Lazy LoadingloadComponent, Child Routes, Parameter als Inputs und Parameter-Vererbung (neuer Standard in v22).Routing
  • 08Guards & ResolvercanActivate, canMatch, canDeactivate und resolve als Funktionen, mit Redirects über UrlTree / RedirectCommand.Routing
  • 09Signal Forms — die GrundlagenFormulare auf Basis von Signals: form(), [formField], schemabasierte Validierung. Stabil seit v22.Formulare
  • 09Signal Forms — fortgeschrittenEigene und feldübergreifende Validierung, async/HTTP mit Debounce, dynamische Listen, disabled/hidden, wiederverwendbare Schemas.Formulare
  • 09Typisierte Reactive FormsTypisierte FormGroup, nonNullable, FormArray — und wie sie neben Signal Forms bestehen.Formulare
  • 10HttpClient, Interceptors & die API-SchichtHttpClient ohne Setup (v21), Fetch als Standard (v22), funktionale Interceptors und eine API-Schicht mit DTO-Mapping.HTTP & Daten
  • 11Performance — eine ChecklisteWas wirklich zählt: OnPush + Signals, track, @defer, Lazy Routes, Bilder, Bundles und Hydration.Qualität & Performance
  • 11Testen mit VitestVitest ist ab v21 der Standard-Runner. TestBed, Komponenten mit Signals, Services, HTTP und Harnesses.Qualität & Performance
  • 11DevTools: ein Blick in deine AppChrome DevTools und Angular DevTools Schritt für Schritt: was jedes Panel zeigt, mit Übungen, die auf dieser Website funktionieren.Qualität & Performance
  • 11Angular AriaHeadless, barrierefreie Komponenten, die du nach Belieben stylst: Tabs, Accordion, Menü, Listbox...Qualität & Performance
  • 12SSR, Prerendering & Render ModesWann auf dem Server gerendert wird, wann beim Build und wann nur im Browser: RenderMode pro Route, app.routes.server.ts und die echten Kosten.SSR & Hydration
  • 12Hydration: Event Replay & inkrementellWie der Browser das Server-HTML übernimmt, ohne es neu zu rendern: vollständige Hydration, Event Replay, @defer (hydrate on …) und Mismatch-Fehler.SSR & Hydration
  • 12Servertauglicher Codewindow gibt es auf dem Server nicht: PLATFORM_ID, afterNextRender, DOCUMENT, TransferState, der HTTP-Cache und PendingTasks.SSR & Hydration
  • 13Micro FrontendsWann es sich lohnt, eine App in mehrere Deployments aufzuteilen und wann es nur Komplexität ist: Native Federation, Module Federation, iframes, Web Components.Architektur im großen Maßstab
  • 13Web Components mit Angular ElementscreateCustomElement: eine Angular-Komponente, die überall als HTML-Tag nutzbar ist, plus Kommunikation zwischen Apps über Events und BroadcastChannel.Architektur im großen Maßstab
  • 13Monorepo, Bibliotheken & GrenzenEin Workspace mit mehreren Apps und Bibliotheken: ng generate library, Nx, Secondary Entry Points, Publishing und Abhängigkeitsregeln.Architektur im großen Maßstab
  • 13Hexagonale Architektur (Ports & Adapters)Eine Domäne ohne Angular, Ports als abstrakte Klassen und austauschbare Adapter: HTTP, localStorage oder In-Memory, ohne die UI anzufassen.Architektur im großen Maßstab
  • 14Signals unter der HaubeDer reaktive Graph: Producer und Consumer, Push-Pull, warum computed lazy und glitch-frei ist, das Diamond-Problem und wann Effects laufen.Fortgeschrittene Reaktivität
  • 14Fortgeschrittenes RxJS: Operatoren höherer OrdnungswitchMap, mergeMap, concatMap und exhaustMap an einem Live-Diagramm, dazu Retry mit Backoff, shareReplay und wie du Leaks vermeidest.Fortgeschrittene Reaktivität
  • 14NgRx SignalStoreState Management im großen Stil auf Signals: withState, withComputed, withMethods, rxMethod, Entities und Hooks — und wann ein einfacher Store reicht.Fortgeschrittene Reaktivität
  • 14Zustandsautomaten mit SignalsKeine unmöglichen Zustände mehr: ein typisierter Automat auf Signals, mit Übergängen, Guards und einem Live-Zustandsdiagramm.Fortgeschrittene Reaktivität
  • 15WebSockets: Echtzeit, die das Netz überstehtEin typisierter Socket als Signals: Reconnect mit Backoff und Jitter, Heartbeat, ein Postausgang im Offline-Modus und SSR-Sicherheit.Echtzeit & offline
  • 15Optimistische Updates & RollbackEine sofortige UI, die ehrlich bleibt: Snapshot und Rollback, Antworten in falscher Reihenfolge, Idempotenzschlüssel.Echtzeit & offline
  • 15Offline-first: Service Worker & CachingDer Angular Service Worker: Caching-Strategien, Update-Hinweise und ein Postausgang für Änderungen, die offline entstehen.Echtzeit & offline
  • 16Web WorkersSchwere Berechnungen, ohne die UI zu blockieren: ein echter Worker in der Seite, Message Passing und wann es sich nicht lohnt.Fortgeschrittene UI & Performance
  • 16Riesige Listen: Virtual Scroll100.000 Zeilen ohne Ruckeln: CDK Virtual Scroll, itemSize, trackBy und die Alternativen (Paginierung, Infinite Scroll).Fortgeschrittene UI & Performance
  • 16Moderne Animationen & View Transitionsanimate.enter und animate.leave statt des veralteten @angular/animations, CSS-Transitions und View Transitions bei der Navigation.Fortgeschrittene UI & Performance
  • 16Memory Leaks finden und behebenSubscriptions, Timer und Listener, die ihre Komponente überleben – wie du sie in den DevTools findest und schließt.Fortgeschrittene UI & Performance
  • 17Sicherheit: XSS, Sanitizing & CSPWas Angular automatisch gegen XSS tut, wann bypassSecurityTrust gefährlich wird, dazu CSP mit Nonce, Trusted Types und XSRF.Sicherheit & Globalisierung
  • 17Authentifizierung: Tokens & RefreshEin Interceptor, der das Token anhängt, bei 401 einmal erneuert und die wartenden Requests wiederholt — dazu, wo du das Token aufbewahrst.Sicherheit & Globalisierung
  • 17OAuth 2.1 & OpenID Connect mit PKCEDer Authorization-Code-Flow mit PKCE Schritt für Schritt: Verifier und Challenge, State und Nonce, das ID-Token und warum ein BFF sicherer ist.Sicherheit & Globalisierung
  • 17Internationalisierung (i18n)$localize, das i18n-Attribut, ICU plural/select, ein Build pro Sprache vs. Übersetzungen zur Laufzeit und Formatierung nach Locale.Sicherheit & Globalisierung