Vytváření webových uživatelských rozhraní pomocí ASP.NET Core zahrnuje řadu nástrojů a technologií, které umožňují vytváření efektivních, responzivních a optimalizovaných webových aplikací. Jedním z klíčových prvků této platformy jsou pomocníci tagů (Tag Helpers), které umožňují snadno přidávat různé funkce do HTML kódu bez nutnosti psaní velkého množství JavaScriptu nebo komplexního C# kódu. V této kapitole se zaměříme na některé z nejběžnějších pomocníků tagů, jako jsou Cache Tag Helper, Environment Tag Helper, a jejich využití při optimalizaci výkonu a přizpůsobení aplikace pro různé prostředí.

Jedním z prvních kroků při práci s ASP.NET Core je správné nastavení a použití různých metod pro předávání a zobrazení dat. Například při vytváření akce v kontroleru, jako je Shipper, je důležité přidat parametr pro přijetí entity „shipper“ prostřednictvím dotazu. Tento parametr pak lze předat do pohledu, kde je zobrazen uživateli. Tento proces ukazuje, jak ASP.NET Core usnadňuje práci s dynamickými daty a jejich zobrazení v reálném čase. Příklad metody v kontroleru může vypadat takto:

csharp
public IActionResult Shipper(Shipper shipper)
{ return View(shipper); }

Na úrovni pohledu pak můžeme vytvořit Razor view, které zobrazuje detaily o odesílateli, jak ukazuje následující kód:

html
@model Shipper @{ ViewData["Title"] = "Shippers"; } <h2>@ViewData["Title"]</h2> <p>Shipper Id: @Model.ShipperId</p> <p>Company Name: @Model.CompanyName</p> <p>Phone: @Model.Phone</p>

Takto vytvořený kód umožňuje efektivní zobrazení informací o odesílatelích přímo na stránce, což je jeden z hlavních principů dynamických webových aplikací.

Další užitečnou funkcí ASP.NET Core je práce s cachováním obsahu pomocí Cache Tag Helper. Tento nástroj výrazně zvyšuje výkon aplikace tím, že uchovává často přístupná data v paměti. Pokud jsou data opakovaně požadována, mohou být načtena z cache, což ušetří čas a systémové prostředky. V ASP.NET Core existují dva hlavní typy cachování: paměťové cache (in-memory cache) a distribuované cache (distributed cache), které se liší v závislosti na potřebách aplikace.

Paměťové cache je ideální pro aplikace běžící na jednom webovém serveru nebo v malém clusteru serverů, kde je zaručena session affinity, tedy že požadavky od stejného klienta jsou vždy obsluhovány stejným serverem. Pro rozsáhlejší aplikace, které běží na více serverech nebo v cloudovém prostředí, je vhodné využít distribuované cache jako Redis nebo SQL Server, což umožňuje efektivní sdílení cache mezi více servery.

Pomocí atributů jako expires-after, expires-on a expires-sliding můžeme specifikovat, jak dlouho má být cache platná. Například pokud chceme, aby určité data byly uchovávány v cache po dobu 20 minut, použijeme atribut expires-after:

html
<cache expires-after="00:20:00">
<!-- Content to cache here --> </cache>

Tento kód způsobí, že obsah bude uchováván v paměti po dobu 20 minut, což je ideální pro obsah, který se nemění příliš často, ale stále vyžaduje rychlý přístup.

Dalším užitečným nástrojem je Environment Tag Helper, který umožňuje vykreslovat obsah pouze v určitých prostředích. To je užitečné například pro zobrazení testovacích dat nebo instrukcí pro vývojáře, které nechceme, aby byly viditelné ve finální verzi aplikace. Tento pomocník se používá s atributem names, který definuje seznam prostředí, kde bude obsah vykreslen. Můžeme také použít atribut exclude, abychom zajistili, že obsah nebude vykreslen v určitém prostředí.

Příklad využití Environment Tag Helper:

html
<environment names="Development,Staging"> <p>Development and staging specific content goes here</p> </environment>

Tento blok kódu se vykreslí pouze v prostředí "Development" nebo "Staging", což znamená, že ve výrobním prostředí bude tento obsah skryt.

Pro optimalizaci webových aplikací v ASP.NET Core je důležité také mít na paměti, jakým způsobem se přenášejí komplexní objekty mezi stránkami. Při práci s URL je třeba dbát na omezení délky dotazů, která jsou omezena na přibližně 1000 znaků. Pro předávání větších objektů je lepší použít POST metodu místo GET, aby se data mohla odesílat ve formátu těla požadavku, nikoli v URL.

Když už mluvíme o výkonu, není možné opomenout význam správného využití nástrojů pro monitorování a diagnostiku, jako jsou vývojářské nástroje prohlížeče. Tyto nástroje umožňují sledovat jak se generují URL adresy, jaký obsah je cachován, a jak jsou vykreslovány různé části aplikace. To je klíčové pro identifikaci a odstranění potenciálních problémů s výkonem aplikace.

Endtext

Jak efektivně spravovat relační data pomocí SQL Serveru a EF Core?

Pokud chcete spravovat relační data pomocí SQL Serveru a Entity Frameworku (EF) Core, jedním z klíčových aspektů, na které se zaměřujeme, je správné připojení k databázi a volba správné autentizace. Tento proces zahrnuje jak základní nastavení připojení, tak výběr vhodného modelu mapování pro různé dědičné hierarchie objektů.

Při práci s SQL Serverem je často nutné správně nastavit připojení k databázi. Použití správného řetězce připojení je nezbytné pro zajištění bezpečnosti a správného fungování aplikace. Příklad takového nastavení připojení v kódu může vypadat takto:

csharp
builder.MultipleActiveResultSets = true; builder.Encrypt = true; builder.TrustServerCertificate = true; builder.ConnectTimeout = 10;

Uživatelské rozhraní aplikace často umožňuje uživateli vybrat mezi různými možnostmi připojení: k SQL Serveru na místním počítači, k databázi v Azure nebo k Azure SQL Edge. Tento výběr může být implementován prostřednictvím jednoduchého menu v konzolové aplikaci, kde uživatel zadá odpovídající volbu podle konkrétního scénáře:

csharp
WriteLine("Connect to:"); WriteLine(" 1 - SQL Server on local machine"); WriteLine(" 2 - Azure SQL Database"); WriteLine(" 3 - Azure SQL Edge");

Další důležitou částí připojení je autentizace. Možnosti autentizace, jak ukazuje následující ukázka, mohou zahrnovat jak Windows Integrated Security, tak SQL Login s uživatelským jménem a heslem:

csharp
WriteLine("Authenticate using:");
WriteLine(" 1 - Windows Integrated Security"); WriteLine(" 2 - SQL Login, for example, sa");

Pokud je vybrána autentizace pomocí SQL Login, uživatel musí zadat správné heslo pro zajištění přístupu k databázi:

csharp
Write("Enter your SQL Server password: "); string? password = ReadLine();

Důležité je také správně validovat zadané údaje, jako je cena produktu, pokud aplikace vyžaduje zadání specifické hodnoty pro filtrování dat v databázi. EF Core umožňuje jednoduše zpracovávat data a provádět filtraci pomocí LINQ, což činí aplikaci efektivní při práci s databázemi.

Pokud jde o mapování dědičných hierarchií v EF Core, zde je možné využít několik různých strategií. Nejčastější je strategie table-per-hierarchy (TPH), která využívá jednu tabulku pro všechny třídy v hierarchii. Například v případě dědičnosti mezi třídami Person, Student a Employee by tabulka vypadala takto:

sql
CREATE TABLE [People] (
[Id] int NOT NULL IDENTITY, [Name] nvarchar(max) NOT NULL, [Discriminator] nvarchar(max) NOT NULL, [Subject] nvarchar(max) NULL, [HireDate] nvarchar(max) NULL, CONSTRAINT [PK_People] PRIMARY KEY ([Id]) );

TPH strategie je jednoduchá a vykazuje vysoký výkon, avšak může být méně flexibilní při práci s komplexními dědičnými strukturami, protože všechny sloupce musí být nullable. Pro tento případ existují i další možnosti mapování, například table-per-type (TPT) nebo table-per-concrete-type (TPC), které poskytují jiné výhody a nevýhody.

TPT strategie vytváří samostatné tabulky pro každý typ (například pro studenty a zaměstnance), což znamená lepší normalizaci dat a úsporu místa. Příklad této strategie vypadá následovně:

sql
CREATE TABLE [People] (
[Id] int NOT NULL IDENTITY, [Name] nvarchar(max) NOT NULL, CONSTRAINT [PK_People] PRIMARY KEY ([Id]) ); CREATE TABLE [Students] ( [Id] int NOT NULL, [Subject] nvarchar(max) NULL, CONSTRAINT [PK_Students] PRIMARY KEY ([Id]), CONSTRAINT [FK_Students_People] FOREIGN KEY ([Id]) REFERENCES [People] ([Id]) ); CREATE TABLE [Employees] ( [Id] int NOT NULL, [HireDate] nvarchar(max) NULL, CONSTRAINT [PK_Employees] PRIMARY KEY ([Id]), CONSTRAINT [FK_Employees_People] FOREIGN KEY ([Id]) REFERENCES [People] ([Id]) );

TPC strategie jde ještě dál a zajišťuje, že každá konkrétní třída bude mít vlastní tabulku s daty. Tento způsob mapování může být výhodný pro komplexní objekty, kde každá třída má velmi odlišné vlastnosti.

Při implementaci těchto strategií je třeba pečlivě zvažovat, jaký přístup bude nejefektivnější pro konkrétní aplikaci. TPH je vhodné pro scénáře, kde je důležitý výkon a jednoduchost, zatímco TPT nebo TPC mohou být lepší pro složitější datové struktury, které vyžadují lepší oddělení dat mezi jednotlivými typy.

Důležité je také věnovat pozornost bezpečnosti a správnému nastavení připojení k databázím, a to jak v případě lokálních SQL Serverů, tak cloudových databází, například v Azure. Při práci s Azure SQL Edge, kde se používají šifrování a certifikáty, je nezbytné dbát na správné nastavení připojení, aby byla zajištěna bezpečnost dat a integrita komunikace mezi aplikací a databází.

Jak měřit výkonnost a efektivitu paměti při práci s pamětí a řetězci v C#

Při vývoji aplikací v jazyce C# je efektivní správa paměti a měření výkonnosti nezbytnou součástí optimalizace kódu. V tomto kontextu se často setkáváme s nástroji jako je Stopwatch, GC (garbage collector) a různé metody pro měření a optimalizaci výkonu. Následující text ukazuje praktické techniky pro sledování využití paměti a výkonu při práci s pamětí a řetězci v C#.

Jedním z nástrojů pro měření je třída Stopwatch, která umožňuje přesně měřit čas, jaký trvá vykonání určitého úkolu. Tento čas je zvláště užitečný při benchmarkingu výkonu a analýze úzkých míst v kódu. Kromě měření času je důležitým aspektem i sledování využití fyzické a virtuální paměti, které nám poskytne informace o efektivitě správy paměti v naší aplikaci.

Měření využití paměti pomocí třídy GC

Metoda Start třídy Recorder ukazuje techniku, jak manuálně vyvolat sběr garbage collection před zaznamenáním využití paměti. Tento postup se používá v situacích, kdy potřebujeme mít jistotu, že všechny nevyužívané objekty byly skutečně uvolněny, než začneme měřit využití paměti. I když by se tento přístup v běžné produkční aplikaci neměl často používat, je výjimkou, která je zde potřebná k dosažení co nejpřesnějších měření.

csharp
public static void Start() { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); bytesPhysicalBefore = GetCurrentProcess().WorkingSet64; bytesVirtualBefore = GetCurrentProcess().VirtualMemorySize64; timer.Restart(); }

Tento postup slouží k vyčištění paměti a odstranění nevyužívaných objektů před tím, než začneme sbírat data o výkonu aplikace. Naopak metoda Stop zaznamená využití paměti po vykonání určitého úkolu a vypíše rozdíl mezi předchozím a aktuálním stavem paměti.

Příklad měření výkonnosti

V následujícím příkladu generujeme pole 10 000 celých čísel a měříme, jakým způsobem tento proces ovlivní využití paměti a čas.

csharp
Recorder.Start();
int[] largeArrayOfInts = Enumerable.Range(1, 10_000).ToArray(); Thread.Sleep(new Random().Next(5, 10) * 1000); Recorder.Stop();

Výsledek běhu tohoto kódu může být ovlivněn několika faktory, včetně hardware, operačního systému a aktuální zátěže počítače. Příklad ukazuje výsledky na dvou různých strojích:

  • Na jednom počítači se využije 827,392 fyzických bajtů a 131,072 virtuálních bajtů během 6 sekund.

  • Na jiném stroji s procesorem Apple M1 se využije pouze 294,912 fyzických bajtů, ale 10,485,760 virtuálních bajtů během stejného časového úseku.

Měření efektivity při práci s řetězci

Jedním z nejběžnějších úkolů v programování je manipulace s řetězci. V tomto případě porovnáváme dva způsoby spojování řetězců: pomocí třídy StringBuilder a operátoru +. Třída StringBuilder je vhodná pro časté operace s řetězci, protože se do paměti ukládá pouze jedna instance, která se postupně rozšiřuje. Naopak operátor + vytváří při každé operaci nový řetězec, což je mnohem náročnější na paměť i čas.

csharp
SectionTitle("Using StringBuilder");
Recorder.Start(); System.Text.StringBuilder builder = new(); for (int i = 0; i < numbers.Length; i++) { builder.Append(numbers[i]); builder.Append(", "); } Recorder.Stop(); SectionTitle("Using string with +"); Recorder.Start(); string s = string.Empty; for (int i = 0; i < numbers.Length; i++) { s += numbers[i] + ", "; } Recorder.Stop();

Výsledek ukazuje výrazný rozdíl mezi těmito dvěma metodami:

  • Při použití StringBuilder bylo využito pouze 1 MB fyzické paměti a operace trvala přibližně 1 milisekundu.

  • Při použití operátoru + bylo využito více než 11 MB fyzické paměti a operace trvala více než 1 sekundu.

Tento rozdíl je způsoben tím, že StringBuilder využívá interní buffer pro připojování nových znaků, zatímco při každém použití operátoru + vzniká nový řetězec, což je neefektivní, zvláště v případě většího množství dat.

Praktická doporučení

Pro efektivní práci s řetězci je tedy doporučeno používat StringBuilder místo operátoru +, zejména v cyklech nebo při práci s velkým množstvím dat. Tato praxe výrazně zlepší výkonnost aplikace a sníží nároky na paměť.

Pro pokročilé měření výkonnosti je k dispozici knihovna Benchmark.NET, která poskytuje přesné a opakovatelné výsledky pro různé scénáře. Můžeme ji využít k porovnání různých metod spojování řetězců nebo jiných operací v C#. Tento nástroj umožňuje nejen měřit čas, ale i další parametry, jako je využití paměti, což činí benchmarking mnohem spolehlivější.

Benchmarking s Benchmark.NET

Knihovna Benchmark.NET je jedním z nejlepších nástrojů pro přesné měření výkonu v aplikacích C#. Používá se pro měření a porovnávání různých implementací algoritmů nebo operací, jako je například spojování řetězců. V případě měření efektivity spojování čísel pomocí StringBuilder a + byste mohli implementovat dvě testovací metody, jak je ukázáno v příkladu:

csharp
[Benchmark(Baseline = true)] public string StringConcatenationTest() { string s = string.Empty; for (int i = 0; i < numbers.Length; i++) { s += numbers[i] + ", "; } return s; } [Benchmark] public string StringBuilderTest() { System.Text.StringBuilder builder = new(); for (int i = 0; i < numbers.Length; i++) { builder.Append(numbers[i]); builder.Append(", "); } return builder.ToString(); }

Tato knihovna vám pomůže optimalizovat aplikaci a vybrat nejlepší implementaci pro vaše konkrétní potřeby, ať už jde o efektivitu paměti, rychlost nebo jiné metriky.

Jak pracovat s časovými zónami pomocí třídy TimeZoneInfo

Práce s časovými zónami je nezbytnou součástí vývoje aplikací, které musí správně manipulovat s daty a časy ve více lokalitách. V tomto článku se zaměříme na využití třídy TimeZoneInfo, která nám umožňuje pracovat s časovými zónami v .NET a získávat informace o aktuálním čase v různých lokalitách.

Pro začátek si vytvořte nový konzolový projekt, který bude obsahovat metody pro práci s časovými zónami. Nejprve si připravte třídu, která nám umožní zobrazit informace o dostupných časových zónách, a to nejen ve formě seznamu, ale i podrobněji pro každou jednotlivou zónu.

Zobrazení seznamu časových zón

Jednou z prvních věcí, kterou potřebujeme udělat, je získat všechny časové zóny z operačního systému a seřadit je podle jejich ID. Toho dosáhneme pomocí metody TimeZoneInfo.GetSystemTimeZones(), která vrací kolekci všech časových zón dostupných na systému. Následně můžeme vypisovat každou zónu podle jejího ID.

csharp
static void OutputTimeZones()
{ // Získání časových zón registrovaných v operačním systému ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones(); WriteLine("*"); WriteLine($"* {zones.Count} časových zón:"); WriteLine("*"); // Seřazení časových zón podle ID foreach (TimeZoneInfo zone in zones.OrderBy(z => z.Id)) { WriteLine($"{zone.Id}"); } }

Tato metoda poskytuje základní přehled o dostupných časových zónách. Je však dobré si uvědomit, že některé časové zóny mohou mít různé názvy v závislosti na aktuálním období (např. letní čas versus standardní čas).

Zobrazení informací o DateTime a TimeZoneInfo

Chceme-li zjistit, jak konkrétní čas vypadá v místní a UTC časové zóně, můžeme použít metody ToLocalTime() a ToUniversalTime() třídy DateTime. Tyto metody nám umožní převést čas z jednoho formátu do druhého a zjistit, zda je čas v daný moment v letním čase.

csharp
static void OutputDateTime(DateTime dateTime, string title)
{ SectionTitle(title); WriteLine($"Hodnota: {dateTime}"); WriteLine($"Typ: {dateTime.Kind}"); WriteLine($"Je letní čas: {dateTime.IsDaylightSavingTime()}"); WriteLine($"ToLocalTime(): {dateTime.ToLocalTime()}"); WriteLine($"ToUniversalTime(): {dateTime.ToUniversalTime()}"); }

Tato metoda nám nejenže vypíše čas v různých formátech, ale i informuje, zda daný čas spadá do letního času.

Zobrazení informací o časové zóně

Pro podrobné zobrazení informací o konkrétní časové zóně použijeme třídu TimeZoneInfo. Můžeme se zaměřit na základní informace, jako je název zóny, její základní UTC offset, a také zda je aktuálně aktivní letní čas.

csharp
static void OutputTimeZone(TimeZoneInfo zone, string title) { SectionTitle(title); WriteLine($"ID: {zone.Id}"); WriteLine("Je letní čas (DateTime.Now): {0}", zone.IsDaylightSavingTime(DateTime.Now)); WriteLine($"Standardní název: {zone.StandardName}"); WriteLine($"Letní název: {zone.DaylightName}"); WriteLine($"BaseUtcOffset: {zone.BaseUtcOffset}"); }

Díky této metodě máme přehled o tom, jak se časová zóna chová v daném okamžiku, zda je aktivní letní čas a jaký je rozdíl mezi standardním časem a časem v letním období.

Převod času mezi zónami

Pokud chcete uživateli umožnit převod času mezi různými časovými zónami, můžete použít metodu TimeZoneInfo.ConvertTime(). Uživatel zadá čas v místní zóně a aplikace následně vypíše odpovídající čas v jiné zóně.

csharp
Write("Zadejte časovou zónu nebo stiskněte Enter pro US východní pobřeží: ");
string zoneId = ReadLine()!; if (string.IsNullOrEmpty(zoneId)) { zoneId = "Eastern Standard Time"; } try { TimeZoneInfo otherZone = TimeZoneInfo.FindSystemTimeZoneById(zoneId); OutputTimeZone(otherZone, $"TimeZoneInfo.FindSystemTimeZoneById(\"{zoneId}\")"); SectionTitle($"Jaký je čas v {zoneId}?"); Write("Zadejte místní čas nebo stiskněte Enter pro aktuální čas: "); string? timeText = ReadLine(); DateTime localTime; if (string.IsNullOrEmpty(timeText) || !DateTime.TryParse(timeText, out localTime)) { localTime = DateTime.Now; } DateTime otherZoneTime = TimeZoneInfo.ConvertTime(localTime, TimeZoneInfo.Local, otherZone); WriteLine("{0} {1} je {2} {3}.", localTime, GetCurrentZoneName(TimeZoneInfo.Local, localTime), otherZoneTime, GetCurrentZoneName(otherZone, otherZoneTime)); } catch (TimeZoneNotFoundException) { WriteLine($"Časová zóna {zoneId} nebyla na místním systému nalezena."); } catch (InvalidTimeZoneException) { WriteLine($"Časová zóna {zoneId} obsahuje neplatná nebo chybějící data."); } catch (System.Security.SecurityException) { WriteLine("Aplikace nemá oprávnění číst informace o časových zónách."); } catch (OutOfMemoryException) { WriteLine($"Není dostatek paměti pro načtení informací o zóně {zoneId}."); }

Tento blok kódu poskytuje dynamický vstup pro uživatele, aby zadal svou časovou zónu, a aplikace následně provede výpočet a zobrazí odpovídající čas v požadované zóně.

Co ještě je důležité pochopit

Při práci s časovými zónami je důležité si uvědomit, že některé časové zóny mohou mít různé názvy v závislosti na letním čase, což může vést k chybám při převodu času, pokud není správně zohledněn přechod mezi standardním a letním časem. Proto je nezbytné mít vždy na paměti aktuální stav letního času v každé zóně. Také je dobré provádět kontrolu na možné výjimky, které mohou nastat při práci s časovými zónami, jako je TimeZoneNotFoundException nebo InvalidTimeZoneException, a ošetřit je vhodným způsobem, aby aplikace byla stabilní a spolehlivá.

Jak implementovat zabezpečené API s použitím JWT a CORS v ASP.NET Core?

Pro implementaci zabezpečeného API v technologii ASP.NET Core Minimal APIs je potřeba rozumět několika klíčovým aspektům. Jedním z nich je využití JWT (JSON Web Token) pro autentizaci a autorizaci uživatelů, stejně jako konfigurace CORS (Cross-Origin Resource Sharing), která umožňuje přístup k API z různých domén. V tomto článku se podíváme na to, jak zajistit bezpečné rozhraní pomocí těchto technologií.

V první řadě je nutné nastavit HTTP GET požadavky pro konkrétní cestu, například pro tajnou cestu, která by měla vrátit jméno autentizovaného uživatele. Tento požadavek může vypadat následovně:

csharp
app.MapGet("/", () => "Hello World!").ExcludeFromDescription();
app.MapGet("/secret", (ClaimsPrincipal user) => $"Vítejte, {user.Identity?.Name ?? "bezpečný uživateli"}. Tajná složka je láska.") .RequireAuthorization();

V tomto příkladu je cesta /secret chráněna pomocí RequireAuthorization(), což znamená, že přístup k ní je povolen pouze autorizovaným uživatelům. Pokud je uživatel úspěšně autentizován, zobrazí se zpráva obsahující jeho jméno, jinak se objeví generická zpráva „bezpečný uživateli“.

Dalším krokem je generování JWT pro testovací účely. K tomu slouží příkaz:

bash
dotnet user-jwts create

Po vykonání tohoto příkazu získáte jedinečný identifikátor, jméno a token, jak je uvedeno v následujícím výstupu:

bash
Nový JWT uložen s ID 'd7e22000'. Název: markjprice Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....

Tento token bude následně použit pro autorizaci při volání chráněných cest. Je důležité si pamatovat, že token má platnost a musí být připojen k každému požadavku pomocí hlavičky Authorization: Bearer.

Pro zobrazení podrobností o tokenu lze použít příkaz:

bash
dotnet user-jwts print d7e22000 --show-all

Tento příkaz ukáže informace jako je platnost tokenu, seznam povolených publikum (audiences), a samotný token, který je trojitou částí oddělenou tečkami (header, payload a signature).

Dále je nutné konfigurovat nastavení autentizace v souboru appsettings.Development.json:

json
{
"Authentication": { "Schemes": { "Bearer": { "ValidAudiences": [ "http://localhost:30225", "https://localhost:44344", "http://localhost:5090", "https://localhost:5091" ], "ValidIssuer": "dotnet-user-jwts" } } } }

Tato konfigurace definuje, jaké domény a porty jsou autorizovány k přístupu k API a jaký issuer (vydavatel) tokenu je považován za platný.

Pokud nyní spustíte projekt s HTTPS profil, požadavek na cestu /secret bez platného tokenu vrátí status kód 401 (Unauthorized). Abychom mohli přistupovat k tajné cestě, je nutné poskytnout správný token. Tento proces lze otestovat pomocí nástroje jako je RestClient nebo Postman, kde specifikujeme autorizaci s použitím tokenu ve formátu Bearer:

http
GET https://localhost:5091/secret/
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....

Po úspěšném ověření tokenu server odpoví zprávou s uvedením jména uživatele a tajné složky.

Důležité je si uvědomit, že pro bezpečné a efektivní použití JWT je nezbytné správně nastavit životnost tokenu (vypršení platnosti) a definovat správné publikum (audiences) a vydavatele (issuer). CORS pak zajišťuje, že API bude dostupné pouze pro specifikované domény a porty, což výrazně zvyšuje bezpečnost a brání neautorizovanému přístupu z jiných míst.

Kromě těchto základních nastavení je také dobré mít na paměti, že bezpečnostní mechanismy jako rate-limiting nebo HTTP logging mohou ještě více posílit zabezpečení a sledování požadavků, což je zvlášť užitečné v produkčním prostředí, kde je potřeba monitorovat neobvyklé nebo škodlivé chování.