Appearance
API Authentication
EaseLab uses JWT bearer tokens for API authorization and HTTP-only cookies for refresh token rotation.
Token configuration
| Setting | Default | Location |
|---|---|---|
AccessTokenMinutes | 15 | appsettings.json → Jwt |
RefreshTokenDays | 7 | appsettings.json → Jwt |
Issuer | EaseLabApi | JWT iss claim |
Audience | EaseLabClient | JWT aud claim |
Auth endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /auth/register | Public | Register new lab |
| GET | /auth/lab-slug-preview | Public | Preview URL slug |
| POST | /auth/login | Public | Sign in |
| POST | /auth/verify-2fa | Public | Complete 2FA login |
| POST | /auth/refresh | Cookie | Rotate tokens |
| POST | /auth/logout | Cookie | Revoke refresh token |
| POST | /auth/forgot-password | Public | Request reset email |
| POST | /auth/reset-password | Public | Set new password |
| POST | /auth/verify-email-otp | Public | Verify email via OTP |
| POST | /auth/resend-email-otp | Public | Resend OTP |
| POST | /auth/confirm-email | Public | Verify via email link |
| POST | /auth/impersonate/exchange | Public | Exchange impersonation code |
Mobile auth (/auth/mobile)
| Method | Endpoint | Notes |
|---|---|---|
| POST | /auth/mobile/login | Returns refresh token in body |
| POST | /auth/mobile/verify-2fa | Mobile 2FA completion |
| POST | /auth/mobile/refresh | Body: { "refreshToken": "..." } |
| POST | /auth/mobile/logout | Revokes refresh token |
Login request / response
Request:
json
{ "email": "[email protected]", "password": "..." }Success response:
json
{
"accessToken": "eyJ...",
"expiresAt": "2026-06-26T10:15:00Z",
"user": {
"id": "...",
"email": "[email protected]",
"tenantId": "...",
"isTenantAdmin": true
}
}Set-Cookie: refresh_token (HttpOnly, Secure in production, SameSite=Lax).
JWT claims
| Claim | Description |
|---|---|
sub | User ID |
email | User email |
tenant_id | Tenant GUID (absent for platform admins) |
role | Platform or tenant role names |
Refresh flow
- Client detects 401 or approaching token expiry.
POST /auth/refreshwith refresh cookie (no body).- Server revokes old refresh token, issues new access + refresh tokens.
- On invalid/expired refresh: 401, cookie cleared.
Profile and 2FA (/me)
| Method | Endpoint | Description |
|---|---|---|
| GET | /me | Current user profile |
| PUT | /me | Update profile |
| PUT | /me/password | Change password |
| GET | /me/2fa | 2FA status |
| POST | /me/2fa/setup | Begin TOTP setup |
| POST | /me/2fa/enable | Confirm and enable |
| POST | /me/2fa/disable | Disable 2FA |
Analyzer API key auth
Analyzer devices authenticate with the X-Analyzer-Key header on /integrations/v1/* routes. See Analyzer Integration.
Security headers
Clients should:
- Store access tokens in memory only (not localStorage in production).
- Send credentials (
credentials: 'include') for refresh requests. - Use HTTPS in all non-development environments.