Autentizace¶
API podporuje více metod přihlášení pod controllerem AuthController (route api/pwa-auth), plus samostatný QR/DeviceToken flow (DeviceAuthController, route api/device-auth). Starý PIN-only endpoint /api/login je zachován jako obsolete.
Od v1.0.43 vyžaduje WebApi přes globální FallbackPolicy autentizovaný požadavek na všech endpointech (kromě explicitně [AllowAnonymous]) — nejen na controllerech dědících z BaseApiController.
POST /api/pwa-auth/login¶
Přihlášení pomocí UserId + PIN. Vrací JWT access token a refresh token.
Request¶
| Pole | Typ | Popis |
|---|---|---|
userId |
string | ID uživatele (číselné jako string) |
pin |
string | PIN uživatele (4–6 číslic) |
Response 200 OK¶
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "base64encodedRefreshToken==",
"expiresIn": 28800,
"user": {
"id": 123,
"userName": "jnovak",
"fullName": "Jan Novák"
}
}
| Pole | Typ | Popis |
|---|---|---|
accessToken |
string | JWT Bearer token (platný expiresIn sekund) |
refreshToken |
string | Token pro obnovení přístupu |
expiresIn |
int | Platnost v sekundách (výchozí: 28 800 = 8 hodin) |
user.id |
long | ID uživatele |
user.userName |
string | Přihlašovací jméno |
user.fullName |
string | Celé jméno |
Response 401 Unauthorized¶
{ "message": "Uživatel nenalezen." }
{ "message": "Účet není aktivní." }
{ "message": "Neplatné přihlašovací údaje." }
Další přihlašovací endpointy (api/pwa-auth)¶
Všechny vrací stejnou strukturu odpovědi jako /api/pwa-auth/login (accessToken, refreshToken, expiresIn, user).
| Endpoint | Metoda | Vstup | Popis |
|---|---|---|---|
/api/pwa-auth/login-password |
POST | userName, password |
Přihlášení jménem a heslem (jako v Eva.Manager); používá PWA a MAUI |
/api/pwa-auth/login-pin |
POST | userName, pin |
Přihlášení jménem a PIN — alternativa pro terminály s omezenou klávesnicí; MAUI zkouší nejdřív heslo, pak PIN jako fallback |
/api/pwa-auth/refresh |
POST | accessToken (expirovaný) |
Stateless refresh — JwtTokenService.GetUserIdFromExpiredToken ověří podpis a vydá nový token, pokud access token expiroval před méně než 24 hodinami (grace period); nevyžaduje uložený refresh token v DB |
GET /api/me¶
Vrátí informace o aktuálně přihlášeném uživateli dle JWT. Vyžaduje platný Bearer token.
QR / DeviceToken přihlášení (api/device-auth)¶
Dlouhodobý přihlašovací mechanismus pro mobilní zařízení (PWA i MAUI) — uživatel jednou naskenuje QR kód vygenerovaný v Eva.Manager a zařízení si uloží dlouhodobý DeviceToken, který si při každém spuštění vymění za krátkodobý JWT.
| Endpoint | Metoda | Autorizace | Popis |
|---|---|---|---|
/api/device-auth/generate-code |
POST | [Authorize] |
Volá Eva.Manager po přihlášení uživatele; vygeneruje jednorázový kód platný 10 minut (DeviceToken:RegistrationCodeExpirationMinutes), vrácený i jako qrContent (EVA-DEV:{code}) pro QR |
/api/device-auth/activate |
POST | [AllowAnonymous] |
Volá zařízení (PWA/MAUI) po naskenování QR; aktivuje kód a vydá dlouhodobý DeviceToken (DeviceToken:ExpirationDays, výchozí 90 dní) |
/api/device-auth/exchange |
POST | [AllowAnonymous] |
Vymění platný DeviceToken za krátkodobý JWT access + refresh token; volá se při startu aplikace nebo po expiraci JWT |
/api/device-auth/tokens |
GET | [Authorize] |
Seznam aktivních device tokenů přihlášeného uživatele |
POST /api/device-auth/activate
Content-Type: application/json
{ "code": "EVA-DEV:AB12CD34", "deviceName": "iPhone Jan Novák" }
Neplatný, expirovaný nebo revokovaný token vrací 400/401 s tělem { "message": "..." }.
Admin přehled a hromadné odvolání tokenů tenantu je na stránce /security v Eva.Manager — viz Bezpečnost.
Použití tokenu¶
Přidejte Authorization header ke každému chráněnému požadavku:
JWT Claims¶
Token obsahuje tyto standardní claims:
| Claim | Zdroj | Popis |
|---|---|---|
sub (NameIdentifier) |
ApplicationUser.Id |
Identifikátor uživatele |
name |
FirstName + " " + LastName |
Celé jméno |
userName |
ApplicationUser.UserName |
Přihlašovací jméno |
role |
ASP.NET Identity role | Přiřazené role (Admin, Manager, User…) |
Přístup k ID přihlášeného uživatele v controlleru:
// V controlleru dědicím z BaseApiController:
var userId = CurrentUserId; // string — hodnota sub claim
POST /api/login ⚠️ OBSOLETE¶
Starý endpoint zachovaný pro zpětnou kompatibilitu s mobilní aplikací. Pouze ověří PIN, nevrací token.
Nepoužívat pro nové integrace. Použijte /api/auth/login.
Konfigurace JWT¶
appsettings.json (Eva.Mobile.WebApi):
"Jwt": {
"Issuer": "Eva.Mobile.WebApi",
"Audience": "Eva.Mobile",
"SecretKey": "<min. 32 znaků>",
"TokenExpirationHours": 8
}
Produkce
SecretKey musí být nastaven přes proměnnou prostředí JWT_SECRET_KEY. Nikdy nedávejte produkční klíč do appsettings.json.
Ochrana vlastních endpointů¶
Nové controllery dědí z BaseApiController:
[ApiController]
[Route("api/[controller]")]
public class MyController : BaseApiController
{
// CurrentUserId — ID přihlášeného uživatele z JWT claims
// Automaticky vyžaduje platný JWT přes [Authorize]
}
Architektura¶
POST /api/pwa-auth/login | login-password | login-pin
└── AuthController.Login() / LoginPassword() / LoginPin()
├── UserManager.FindByIdAsync() / FindByNameAsync()
├── ověření PIN / hesla
└── GenerateAuthResponse()
└── JwtTokenService.GenerateTokensAsync()
└── UserManager.GetRolesAsync() — přidá role a tenant_id do claims
POST /api/pwa-auth/refresh
└── JwtTokenService.GetUserIdFromExpiredToken() — stateless, grace period 24 h
POST /api/device-auth/generate-code → activate → exchange
└── DeviceTokenDataService — DB-backed dlouhodobý token, nezávislý na JWT
Klíčové soubory:
| Soubor | Popis |
|---|---|
Controllers/AuthController.cs |
Login endpointy (api/pwa-auth) |
Controllers/MeController.cs |
Info o přihlášeném uživateli (api/me) |
Controllers/DeviceAuthController.cs |
QR/DeviceToken flow (api/device-auth) |
Controllers/BaseApiController.cs |
Abstraktní základ s [Authorize] |
Services/JwtTokenService.cs |
Generování JWT, refresh tokenů a stateless refresh |
Services/WebApiTenantAccessor.cs |
Čte tenant_id z JWT claims pro EF Core tenant filtry |
Data/Services/DeviceTokenDataService.cs |
Vydávání, validace a odvolání DeviceToken záznamů |
Controllers/LoginController.cs |
Starý endpoint (obsolete) |