AngularAtlased. 22.2

Cap. 17Securitate & globalizare72 / 75

Securitate: XSS, sanitizare & CSP

Ce face Angular automat împotriva XSS, când devine periculos bypassSecurityTrust, plus CSP cu nonce, Trusted Types și XSRF.

Angular pornește de la o regulă simplă: orice valoare legată în template e considerată nesigură, până la proba contrarie. Interpolarea escapează textul. [innerHTML] trece prin sanitizer. URL-urile cu scheme periculoase sunt neutralizate. De aceea un XSS într-o aplicație Angular apare aproape mereu când cineva ocolește aceste protecții, nu când le folosește.

Pagina arată ce face Angular automat, unde sunt „ușile laterale” pe care le cauți la code review și cum adaugi a doua linie de apărare: Content Security Policy și Trusted Types. La final e protecția XSRF din HttpClient.

De ce contează
Un singur XSS înseamnă că atacatorul rulează JavaScript în pagina ta, cu sesiunea utilizatorului: citește date, trimite request-uri în numele lui, fură token-uri din localStorage. Protecțiile implicite acoperă cazurile obișnuite. Restul depinde de ce faci tu cu bypassSecurityTrust* și cu DOM-ul.

Contextele de securitate

Angular alege tratamentul după unde ajunge valoarea. În text o escapează. În HTML ([innerHTML]) o sanitizează: păstrează tagurile de formatare și elimină <script>, atributele on*, <iframe> și URL-urile periculoase. La URL ([href], [src]) neutralizează scheme ca javascript:. Resource URL (sursa unui <iframe> sau a unui script) e cel mai strict context, pentru că acolo un URL înseamnă cod executat.

<!-- Interpolare: textul e ESCAPAT — „<b>” apare literal, nu devine tag -->
<p>{{ comment.text }}</p>

<!-- [innerHTML]: HTML-ul e SANITIZAT — rămân tagurile de formatare, dispar script-urile și handler-ele -->
<div [innerHTML]="comment.html"></div>

<!-- URL-uri: javascript: și alte scheme periculoase devin „unsafe:…” -->
<a [href]="profile.website">site</a>

<!-- Stiluri: valorile din [style] sunt și ele verificate -->
<div [style.background-image]="'url(' + user.avatar + ')'"></div>
LiveSanitizer-ul Angular, pe viu
Randat cu [innerHTML] (sanitizat automat)

Salut, lume! Vezi docs.

Ce rămâne după sanitizer.sanitize(SecurityContext.HTML, …)
<p><b>Salut</b>, <em>lume</em>! Vezi <a href="https://angular.dev">docs</a>.</p>

nimic eliminat conținutul era deja sigur.

Cu bypassSecurityTrustHtml(…) Angular ar insera exact textul din căsuță, inclusiv handler-ele de evenimente. De aceea demo-ul nu face asta.

Alege un exemplu periculos: în stânga vezi ce randează [innerHTML], în dreapta exact ce a lăsat sanitizer-ul, iar dedesubt ce a fost eliminat. În modul de dezvoltare, Angular scrie în consolă un avertisment de fiecare dată când elimină ceva; e normal.

URL-uri

Un link cu href venit de la utilizator („site-ul meu”) e un vector clasic de atac: javascript:alert(document.cookie) rulează cod la click. Angular prefixează valorile nesigure cu unsafe:, deci browserul nu le mai poate executa. Schemele obișnuite (https:, mailto:, căi relative) trec neschimbate.

LiveCe primește [href]

Template: <a [href]="url()"> → atributul din DOM:

link-ul randat
Încearcă javascript: și data:. Atributul din DOM primește prefixul unsafe:. Click-ul nu mai execută nimic.

bypassSecurityTrust și ușile laterale

DomSanitizer are cinci metode bypassSecurityTrust… (Html, Script, Style, Url, ResourceUrl). Ele marchează o valoare ca sigură, iar Angular nu o mai verifică. Sunt legitime doar pentru conținut pe care îl construiești și controlezi tu, de exemplu URL-ul unui embed format dintr-un id validat. Pe date de la utilizator sau de la un API extern, fiecare apel e o vulnerabilitate. Documentația Angular le marchează ca „security sensitive”: caută-le la fiecare review.

import { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';

export class Embed {
  private readonly sanitizer = inject(DomSanitizer);

  // ✓ Doar pentru conținut pe care îl CONTROLEZI: un URL construit de tine dintr-un id validat
  readonly video: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(
    `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId())}`,
  );

  // ✗ Niciodată pe ce vine de la utilizator sau de la un API extern
  unsafe(html: string): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(html); // XSS garantat dacă html conține un <img onerror>
  }
}

Mai periculoase sunt căile care nu trec deloc prin Angular: nativeElement.innerHTML, Renderer2.setProperty(…, 'innerHTML', …), document.write, eval și template-urile construite din string-uri la runtime.

// Toate astea OCOLESC sanitizarea Angular — evită-le cu date din afară:
this.el.nativeElement.innerHTML = userHtml;                     // DOM direct
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', userHtml);
document.write(userHtml);
new Function(userCode)();  eval(userCode);
// și template-uri construite din string-uri cu input de la utilizator (compilare JIT la runtime)

// ✓ Alternativa: [innerHTML] (sanitizat) sau, pentru markdown, o bibliotecă de randare + sanitizare

Content Security Policy

CSP e un header prin care îi spui browserului ce scripturi și stiluri are voie să ruleze. Chiar dacă un atacator reușește să injecteze HTML, scriptul lui nu rulează fără nonce-ul sau hash-ul corect. Angular adaugă stiluri inline (stilurile componentelor), așa că are nevoie de nonce. Îl primește fie prin atributul ngCspNonce pe elementul root (serverul îl generează la fiecare răspuns), fie prin token-ul CSP_NONCE.

Alternativa fără server de template-uri e security.autoCsp. CLI-ul calculează la build hash-urile scripturilor inline și pune politica într-un <meta>, deci index.html rămâne cache-uibil. Documentația îi listează limitele: acoperă doar scripturile, unele directive (de ex. frame-ancestors) tot trebuie trimise în header și nu funcționează cu SSR.

import { CSP_NONCE } from '@angular/core';

// Varianta 1 (server-side templating): serverul pune același nonce în header și în index.html
//   <app-root ngCspNonce="r4nd0m-per-request"></app-root>

// Varianta 2: nonce-ul e disponibil la runtime și vrei să poți cache-ui index.html
bootstrapApplication(App, {
  providers: [{ provide: CSP_NONCE, useValue: globalThis.myRandomNonceValue }],
});

Trusted Types

Trusted Types merg un pas mai departe: browserul refuză orice scriere în „sink-uri” periculoase (innerHTML, src de script…) care nu vine printr-o politică aprobată. Angular are politicile lui: angular pentru ce face framework-ul, angular#unsafe-bypass dacă folosești bypassSecurityTrust*, angular#bundler pentru chunk-urile lazy ale CLI-ului. Un innerHTML scris direct în cod devine eroare în loc de vulnerabilitate.

# Minimul pentru o aplicație Angular
Content-Security-Policy: trusted-types angular; require-trusted-types-for 'script';

# Dacă folosești bypassSecurityTrust*
Content-Security-Policy: trusted-types angular angular#unsafe-bypass; require-trusted-types-for 'script';

# Dacă ai chunk-uri lazy create de CLI
Content-Security-Policy: trusted-types angular angular#bundler; require-trusted-types-for 'script';
LiveConstructor de CSP
Header HTTP
Content-Security-Policy:
  script-src 'self' 'nonce-RANDOM_PER_RESPONSE';
  style-src 'self' 'nonce-RANDOM_PER_RESPONSE';
  object-src 'none';
  base-uri 'self';
  frame-ancestors 'none';
  trusted-types angular angular#bundler;
  require-trusted-types-for 'script';
Configurarea în Angular
<!-- index.html: serverul înlocuiește valoarea la fiecare răspuns -->
<app-root ngCspNonce="RANDOM_PER_RESPONSE"></app-root>

// sau, dacă nonce-ul e cunoscut la runtime:
{ provide: CSP_NONCE, useValue: globalThis.myNonce }
Alege cum livrezi nonce-ul și ce folosește aplicația. Header-ul și configurarea Angular se actualizează pe loc.

XSRF / CSRF

Dacă autentificarea se face cu cookie de sesiune, o pagină străină poate trimite un formular către API-ul tău, iar browserul atașează cookie-ul automat. HttpClient are protecția integrată: citește cookie-ul XSRF-TOKEN și trimite valoarea în header-ul X-XSRF-TOKEN. Doar codul de pe domeniul tău poate citi cookie-ul, deci serverul știe de unde vine cererea. Header-ul se pune doar pe request-urile care modifică date (nu pe GET/HEAD), către URL-uri relative sau de pe același origin. Partea de server e obligatorie: serverul setează cookie-ul și verifică header-ul.

import { provideHttpClient, withXsrfConfiguration, withNoXsrfProtection } from '@angular/common/http';

// Implicit: HttpClient citește cookie-ul XSRF-TOKEN și trimite header-ul X-XSRF-TOKEN
// pe request-urile care MODIFICĂ date (POST, PUT, DELETE…) către URL-uri relative / același origin.
provideHttpClient(
  withXsrfConfiguration({ cookieName: 'CSRF-TOKEN', headerName: 'X-CSRF-TOKEN' }), // dacă backend-ul folosește alte nume
);

// Dezactivare (ex. API cu token Bearer, fără cookie de sesiune):
provideHttpClient(withNoXsrfProtection());

Când DA, când NU

Fă asta
  • Lasă Angular să facă binding-ul: interpolare și [innerHTML], nu DOM direct.
  • CSP strict (nonce sau autoCsp) și Trusted Types în producție.
  • Cookie-uri de sesiune HttpOnly, Secure, SameSite și protecția XSRF activă (vezi Autentificare). Pentru login printr-un furnizor extern, vezi OAuth 2.1 / OIDC cu PKCE.
  • Actualizează Angular și dependențele: corecturile de securitate vin în versiuni patch.
Nu face asta
  • bypassSecurityTrustHtml pe conținut de la utilizatori sau din CMS-uri externe.
  • Validare „de securitate” doar în frontend: orice regulă trebuie verificată din nou pe server.
  • Token-uri de acces în localStorage fără CSP: un singur XSS le poate citi.
  • Dezactivarea warning-urilor de sanitizare „ca să nu mai apară în consolă”: ele îți arată exact unde intră HTML nesigur.

Capcane frecvente

  • „Pipe-ul safeHtml” din proiect, care apelează bypassSecurityTrustHtml pe orice: e un XSS reutilizabil. Șterge-l sau limitează-l la surse sigure.
  • Markdown randat cu bypassSecurityTrustHtml: markdown-ul poate conține HTML. Randează-l, apoi trece rezultatul prin sanitizare.
  • Atribute href construite prin concatenare în nativeElement: ocolesc sanitizarea URL-urilor.
  • CSP adăugat „la final” fără testare: chunk-urile lazy sau stilurile inline sunt blocate și aplicația se strică în producție. Pornește cu Content-Security-Policy-Report-Only.
  • XSRF dezactivat cu cookie de sesiune activ: orice site poate face POST-uri în numele utilizatorului.

Fișă rapidă

IMPLICIT (fără să faci nimic)
  {{ x }}            escapat
  [innerHTML]        sanitizat (dispar script, on*, javascript:, iframe…) — warning în dev când elimină ceva
  [href] / [src]     URL-uri periculoase → "unsafe:…"
OCOLIRI (doar pentru conținut controlat de tine — caută-le la code review)
  bypassSecurityTrustHtml / Url / ResourceUrl / Style / Script
  nativeElement.innerHTML, Renderer2.setProperty('innerHTML'), document.write, eval, template-uri din string-uri
CSP
  ngCspNonce="…" pe root  sau  { provide: CSP_NONCE, useValue }  — nonce per răspuns
  "security": { "autoCsp": true }  — hash-uri la build, index.html cache-uibil, NU cu SSR, doar script-src
TRUSTED TYPES
  trusted-types angular [angular#unsafe-bypass] [angular#bundler]; require-trusted-types-for 'script'
XSRF
  XSRF-TOKEN → X-XSRF-TOKEN, doar request-uri care modifică, doar same-origin · withXsrfConfiguration · withNoXsrfProtection
SERVER
  validează tot din nou · cookie-uri HttpOnly + Secure + SameSite · npm audit / actualizări Angular

Cap. 17 · 0 din 4 terminate

Ai terminat lecția?

Marcheaz-o și apare pe harta ta: în cuprins și pe prima pagină.

Se marchează singură după ce citești toată lecția.

  1. Securitate: XSS, sanitizare & CSP
  2. Autentificare: token-uri & refresh
  3. OAuth 2.1 și OpenID Connect cu PKCE
  4. Internaționalizare (i18n)
Vezi toată harta ta

Toate cele 75 de pagini · scrie ca să filtrezi

  • 01Ce e nou în Angular 21 & 22Toate schimbările importante din v21 și v22, pe scurt, cu link către pagina care le explică.Start
  • 01Prima ta aplicație, pas cu pasO listă de lecturi construită de la o componentă goală la o aplicație terminată — signals, @for, input-uri și output-uri, un serviciu și un formular, pas cu pas.Start
  • 01Decizii rapide„Unde pun asta?”, „Signal sau Observable?”, „Shared sau feature?” — răspunsuri scurte la întrebările de zi cu zi.Start
  • 01Întrebări de interviu Angular60 de întrebări reale de interviu pentru junior, mid și senior, cu răspunsul de dat, întrebarea care urmează și greșelile de evitat. Plus o simulare de interviu.Start
  • 02Standalone & bootstrapCum pornește o aplicație fără NgModule: bootstrapApplication, app.config.ts, imports în componentă.Fundamente moderne
  • 02Data binding și evenimenteInterpolare, binding pe proprietăți și pe atribute, evenimente cu $event și filtre de taste și cum e construit [( )] — ce intră în DOM și ce se întoarce.Fundamente moderne
  • 02Control flow: @if, @for, @switchSintaxa de blocuri care înlocuiește *ngIf/*ngFor/ngSwitch, cu track, @empty și verificare exhaustivă.Fundamente moderne
  • 02@let și expresiile noi din templateVariabile locale cu @let, arrow functions, spread, regex, instanceof, comentarii în tag-uri.Fundamente moderne
  • 02@defer — lazy loading în templateÎncarci componente grele doar când e nevoie: triggere, prefetch, placeholder, loading, error.Fundamente moderne
  • 02Class & style bindingsDe ce [class.x] și [style.x] au înlocuit ngClass și ngStyle (cu migrare automată din v21).Fundamente moderne
  • 02Stilurile componentelor și încapsularea:host, cele trei moduri de încapsulare, teme cu variabile CSS și de ce ::ng-deep e ultima soluție.Fundamente moderne
  • 02Pipes: când și cumPipe pur vs impur, pipe custom și cum alegi între pipe, computed() și o metodă.Fundamente moderne
  • 03signal() și computed()Primitivele reactive: stare scriibilă, stare derivată, egalitate, untracked și reguli de imutabilitate.Signals & reactivitate
  • 03effect() — când DA, când NUEfecte secundare sincronizate cu semnale: localStorage, logging, API-uri imperative. Și capcanele lor.Signals & reactivitate
  • 03linkedSignal() — stare derivată editabilăUn semnal care se resetează când se schimbă sursa, dar pe care îl poți și seta manual.Signals & reactivitate
  • 03resource, rxResource, httpResourceDate asincrone ca semnale: status, value, error, reload, anulare automată. Stabile din v22.Signals & reactivitate
  • 03debounced() — semnale cu întârziereVarianta „debounce” a unui semnal, fără RxJS. Perfect pentru căutare.Signals & reactivitate
  • 03Liste: căutare, filtrare, sortare, paginareUn lanț de computed-uri care recalculează doar ce s-a schimbat, cu filtrele ținute în URL, ca un link să redeschidă aceeași vedere.Signals & reactivitate
  • 03Observables de la zeroCe e un Observable, subscribe și unsubscribe, operatorii pe care îi folosești în fiecare săptămână, cold vs hot — și când ajunge un signal.Signals & reactivitate
  • 03Signals ↔ RxJStoSignal, toObservable, takeUntilDestroyed, outputFromObservable — și când RxJS rămâne alegerea bună.Signals & reactivitate
  • 04input() și output()Inputuri ca semnale (required, transform, alias) și outputuri tipizate. Data down, events up.Componente: comunicare
  • 04model() — two-way bindingBanana-in-a-box [( )] cu un singur API. Când îl folosești și când e mai bine input + output.Componente: comunicare
  • 04viewChild & contentChildInterogări ca semnale: viewChild, viewChildren, contentChild, contentChildren, opțiunea read.Componente: comunicare
  • 04Lifecycle & DestroyRefCe hook-uri mai contează în era signals, afterNextRender, DestroyRef și ngOnChanges tipizat.Componente: comunicare
  • 04Content projectionng-content cu select, sloturi multiple, conținut implicit și capcana proiecției condiționale.Componente: comunicare
  • 04ng-template & ngTemplateOutletTemplate-uri ca valori: render props în Angular, context tipizat și personalizare de componente.Componente: comunicare
  • 05Smart vs DumbContainer vs presentational: cine ține starea, cine doar afișează, și cum le împarți corect.Design de componente
  • 05Componente generice <T>Un DataTable<T> sau Select<T> tipizat corect, cu template-uri pentru celule.Design de componente
  • 05Componente dinamiceNgComponentOutlet, createComponent cu inputBinding/outputBinding și un dashboard construit din config.Design de componente
  • 05Directive & host compositionDirective atribut, metadata host: {} și Directive Composition API (hostDirectives).Design de componente
  • 05Controale custom de formularFormValueControl (Signal Forms) vs ControlValueAccessor: un rating cu stele, în ambele variante.Design de componente
  • 05Change detectionOnPush e implicit din v22, zone.js lipsește din v21. Ce declanșează randarea și cum să nu te arzi.Design de componente
  • 06inject() & @Service()Noul decorator @Service() din v22, inject() vs constructor și contextul de injecție.Dependency Injection
  • 06Providers & ierarhia de injectoriRoot vs rută vs componentă, useClass/useValue/useFactory/useExisting și modificatorii optional/self/skipSelf.Dependency Injection
  • 06InjectionToken & provideX()Configurare tipizată, funcții provideFeature(), makeEnvironmentProviders și inițializatori.Dependency Injection
  • 06injectAsync() — servicii lazyÎncarci un serviciu greu abia când ai nevoie de el, cu prefetch la idle.Dependency Injection
  • 07Structura de folderecore / shared / features, ce intră în fiecare și cum arată un feature pe dinăuntru.Arhitectura aplicației
  • 07Shared vs featureCând muți o componentă în shared și (mai ales) când NU. Checklist concret.Arhitectura aplicației
  • 07Interfețe & modeleInterfață inline sau fișier separat? DTO vs model de domeniu, type vs interface, unde le pui.Arhitectura aplicației
  • 07State management cu signalsStore-uri simple pe semnale, facade, stare locală vs globală și când îți trebuie NgRx.Arhitectura aplicației
  • 07Style guide & namingConvențiile oficiale actuale: nume de fișiere fără sufixe, protected, readonly, ordinea membrilor.Arhitectura aplicației
  • 07Barrels, aliasuri & granițeindex.ts, path aliases, API public pe feature și reguli de dependență care se pot verifica automat.Arhitectura aplicației
  • 07Erori: @boundary & ErrorHandlerNoul bloc @boundary din v22.2, ErrorHandler global, erori HTTP și erori din resource.Arhitectura aplicației
  • 08Routing modern & lazy loadingloadComponent, rute copil, parametri ca input-uri și moștenirea parametrilor (default nou în v22).Routing
  • 08Guards & resolverscanActivate, canMatch, canDeactivate și resolve ca funcții, cu redirect prin UrlTree / RedirectCommand.Routing
  • 09Signal Forms — bazeleFormulare construite pe semnale: form(), [formField], validare prin schemă. Stabile din v22.Formulare
  • 09Signal Forms — avansatValidare custom și cross-field, async/HTTP cu debounce, liste dinamice, disabled/hidden, scheme reutilizabile.Formulare
  • 09Reactive Forms tipizateFormGroup tipizat, nonNullable, FormArray — și cum conviețuiesc cu Signal Forms.Formulare
  • 10HttpClient, interceptors & API layerHttpClient fără setup (v21), Fetch implicit (v22), interceptori funcționali și stratul de API cu mapare DTO.HTTP & date
  • 11Performanță — checklistCe chiar contează: OnPush + signals, track, @defer, lazy routes, imagini, bundle și hidratare.Calitate & performanță
  • 11Testare cu VitestVitest e runner-ul implicit din v21. TestBed, componente cu semnale, servicii, HTTP și harness-uri.Calitate & performanță
  • 11DevTools: cum te uiți în aplicațieChrome DevTools și Angular DevTools pas cu pas: ce arată fiecare panou, cu exerciții care merg chiar pe site-ul ăsta.Calitate & performanță
  • 11Angular AriaComponente headless, accesibile, pe care le stilizezi cum vrei: tabs, accordion, menu, listbox...Calitate & performanță
  • 12SSR, prerender & render modesCând randezi pe server, când la build și când doar în browser: RenderMode pe rută, app.routes.server.ts și costurile reale.SSR & hidratare
  • 12Hidratare: event replay & incrementalCum preia browserul HTML-ul de pe server fără să-l refacă: hidratare completă, event replay, @defer (hydrate on …) și erorile de nepotrivire.SSR & hidratare
  • 12Cod compatibil cu serverulwindow nu există pe server: PLATFORM_ID, afterNextRender, DOCUMENT, TransferState, cache-ul HTTP și PendingTasks.SSR & hidratare
  • 13Micro frontendsCând merită să spargi o aplicație în mai multe deploy-uri și când e doar complexitate: Native Federation, Module Federation, iframes, Web Components.Arhitectură la scară
  • 13Web Components cu Angular ElementscreateCustomElement: o componentă Angular folosită ca tag HTML oriunde, plus comunicarea între aplicații prin evenimente și BroadcastChannel.Arhitectură la scară
  • 13Monorepo, librării & granițeUn workspace cu mai multe aplicații și librării: ng generate library, Nx, entry points secundare, publicare și reguli de dependență.Arhitectură la scară
  • 13Arhitectură hexagonală (ports & adapters)Domeniul fără Angular, porturi ca clase abstracte și adaptoare interschimbabile: HTTP, localStorage sau in-memory, fără să atingi UI-ul.Arhitectură la scară
  • 14Semnalele pe dinăuntruGraful reactiv: producători și consumatori, push-pull, de ce computed e lazy și glitch-free, problema diamantului și când rulează efectele.Reactivitate avansată
  • 14RxJS avansat: operatori de ordin superiorswitchMap, mergeMap, concatMap și exhaustMap pe o diagramă live, plus retry cu backoff, shareReplay și cum eviți scurgerile.Reactivitate avansată
  • 14NgRx SignalStoreState management la scară pe semnale: withState, withComputed, withMethods, rxMethod, entități și hooks — și când un store simplu e suficient.Reactivitate avansată
  • 14Mașini de stări cu signalsFără stări imposibile: o mașină tipizată pe signals, cu tranziții, guards și diagrama stărilor, live.Reactivitate avansată
  • 15WebSockets: timp real care rezistă rețeleiUn socket tipizat ca signals: reconectare cu backoff și jitter, heartbeat, coadă de mesaje cât ești offline și siguranță la SSR.Timp real și offline
  • 15Actualizări optimiste și rollbackInterfață instantanee, dar onestă: snapshot și rollback, răspunsuri sosite în altă ordine, chei de idempotență.Timp real și offline
  • 15Offline-first: Service Worker și cacheService Worker-ul Angular: strategii de cache, anunțarea versiunilor noi și o coadă pentru modificările făcute offline.Timp real și offline
  • 16Web WorkersCalcule grele fără să blochezi interfața: un worker real în pagină, comunicare prin mesaje și când nu merită.UI & performanță avansată
  • 16Liste uriașe: virtual scroll100.000 de rânduri fără lag: CDK virtual scroll, itemSize, trackBy și alternativele (paginare, infinite scroll).UI & performanță avansată
  • 16Animații moderne & View Transitionsanimate.enter și animate.leave în locul @angular/animations (depreciat), tranziții CSS și View Transitions la navigare.UI & performanță avansată
  • 16Memory leaks: cum le găsești și le repariSubscripții, timere și listeneri care trăiesc mai mult decât componenta lor — cum îi vezi în DevTools și cum îi închizi.UI & performanță avansată
  • 17Securitate: XSS, sanitizare & CSPCe face Angular automat împotriva XSS, când devine periculos bypassSecurityTrust, plus CSP cu nonce, Trusted Types și XSRF.Securitate & globalizare
  • 17Autentificare: token-uri & refreshUn interceptor care atașează token-ul, reîmprospătează o singură dată la 401 și reia cererile din coadă — plus unde ții token-ul.Securitate & globalizare
  • 17OAuth 2.1 și OpenID Connect cu PKCEFluxul authorization code cu PKCE, pas cu pas: verifier și challenge, state și nonce, ID token-ul și de ce un BFF e mai sigur.Securitate & globalizare
  • 17Internaționalizare (i18n)$localize, atributul i18n, ICU plural/select, build per limbă vs. traduceri la runtime și formatarea după locale.Securitate & globalizare