Web Authentication
NetKey uses industry-standard JWT (JSON Web Tokens) with refresh tokens for secure, stateless authentication. This guide covers how authentication works for the web dashboard and API integrations.
Overview
NetKey implements a two-token authentication system following OAuth 2.0 best practices:
Access Token
Short-lived JWT (1 hour) used to authenticate API requests. Stored in memory for security.
Refresh Token
Long-lived token (14-30 days) stored in HttpOnly cookie. Used to obtain new access tokens.
Authentication Flow
1. Login
When a user logs in with username/password:
{
"username": "user@example.com",
"password": "your-password",
"remember_me": true
}
Response includes:
- Access token in the JSON response body
- Refresh token set as an HttpOnly cookie
- User information (role, group, permissions)
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600,
"user": {
"id": 1,
"username": "user@example.com",
"role": "GROUP_ADMIN",
"group_id": 3,
"group_name": "Acme Corp"
}
}
Set-Cookie: refresh_token=abc123...; HttpOnly; Secure; SameSite=Lax; Max-Age=1209600; Path=/api/auth
2. Using the Access Token
Include the access token in the Authorization header for all API requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
3. Refreshing the Access Token
When the access token expires (after 1 hour), use the refresh token to get a new one. The refresh token is automatically sent via the HttpOnly cookie.
// No body required - refresh token is in the cookie
fetch('/api/auth/refresh', {
method: 'POST',
credentials: 'include' // Important: sends cookies
});
Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}
Set-Cookie: refresh_token=new_token...; HttpOnly; Secure; ...
For security, refresh tokens are rotated on each use. The old token is invalidated and a new one is issued.
4. Logout
Logout invalidates both the access token and refresh token:
fetch('/api/auth/logout', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken
},
credentials: 'include'
});
Token Details
Access Token (JWT) Payload
The access token is a standard JWT containing:
| Claim | Description | Example |
|---|---|---|
user_id |
User's unique identifier | 3 |
username |
User's email/username | "user@example.com" |
role |
User's role | "GROUP_ADMIN" |
group_id |
User's group ID | 3 |
iat |
Issued at (Unix timestamp) | 1704067200 |
exp |
Expiration (Unix timestamp) | 1704070800 |
jti |
Unique token ID | "abc123..." |
Token Lifetimes
| Token Type | Lifetime | Storage |
|---|---|---|
| Access Token | 1 hour | Memory / sessionStorage |
| Refresh Token (default) | 14 days | HttpOnly cookie |
| Refresh Token (remember me) | 30 days | HttpOnly cookie |
Security Features
HttpOnly Cookies
Refresh tokens are stored in HttpOnly cookies, preventing JavaScript access and XSS attacks.
Token Rotation
Refresh tokens are rotated on each use, limiting the window for token theft.
Short-lived Access Tokens
Access tokens expire in 1 hour, minimizing exposure if compromised.
Secure Cookie Flags
Cookies use Secure (HTTPS only) and SameSite=Lax flags to prevent CSRF attacks.
No Sensitive Data in localStorage
User profile data is fetched from the API on each session, never stored persistently.
Multi-Factor Authentication
NetKey supports TOTP-based MFA (compatible with Google Authenticator, Authy, etc.). When MFA is enabled, the login flow requires an additional step:
// Step 1: Initial login returns requires_mfa
{
"requires_mfa": true,
"mfa_type": "totp"
}
// Step 2: Submit with TOTP code
POST /api/auth/login
{
"username": "user@example.com",
"password": "your-password",
"totp_code": "123456"
}
API Keys vs JWT
For programmatic access (integrations, scripts, automation), use API Keys instead of JWT tokens. See the API Reference for details.
| Feature | JWT Tokens | API Keys |
|---|---|---|
| Use case | Web dashboard, user sessions | Integrations, automation |
| Lifetime | 1 hour (access) / 14-30 days (refresh) | Until revoked |
| Scope | Full user permissions | Configurable (read/write) |
| Header | Authorization: Bearer ... |
X-API-Key: nk_live_... |
Error Responses
| Status | Error | Description |
|---|---|---|
401 |
Invalid credentials | Wrong username or password |
401 |
Token expired | Access token has expired, use refresh |
401 |
Invalid refresh token | Refresh token expired or revoked |
403 |
Account disabled | User account has been deactivated |
403 |
MFA required | TOTP code needed to complete login |