Files
bookhoard/docs/developer/api/authentication/overview.md
T
john-okeefe 8a6ea39ed2 docs(auth): document 7-day session authentication with constants
- Add comprehensive authentication overview.md explaining:
  - 7-day session duration for JWT and refresh tokens
  - Constants-based implementation (no hardcoded values)
  - Complete authentication flow (register/login/refresh/logout)
  - Session expiration handling (HTML redirect vs JSON error)
  - Security features (HTTP-only cookies, token rotation)
  - Token storage recommendations
- Update login.md with 7-day expires_in field and cookie MaxAge
- Update register.md with 7-day session duration details
- Update refresh_token.md with expires_in: 604800

Documentation provides complete reference for authentication
endpoints with examples and security considerations.
2026-02-16 16:50:43 -05:00

4.1 KiB
Raw Blame History

Authentication Overview

Bookhoard uses JWT-based authentication with 7-day persistent sessions and refresh tokens for security.

Session Duration

All JWT tokens and refresh tokens are valid for 7 days from creation. This provides a Google-like persistent session experience.

  • JWT Access Token: Valid for 7 days
  • Refresh Token: Valid for 7 days
  • HTTP-only Cookie: Max-Age of 7 days (604800 seconds)

Implementation Details

Session durations are defined using constants to maintain a single source of truth:

// internal/handlers/auth.go
const (
    SessionDuration     = 7 * 24 * time.Hour // 7 days
)

// SessionDurationSec is computed from SessionDuration
var SessionDurationSec = int(SessionDuration.Seconds()) // 604800 seconds

No hardcoded values exist in the codebase. All timeout values use these constants:

  • JWT token exp claim: time.Now().Add(SessionDuration).Unix()
  • Cookie MaxAge: SessionDurationSec
  • API response expires_in: SessionDurationSec

Authentication Flow

1. Registration/Login

When a user registers or logs in:

  1. Server generates a JWT access token (valid for 7 days)
  2. Server creates a refresh token in the database (valid for 7 days)
  3. Server sets an HTTP-only cookie with the JWT token
  4. Server returns JSON response with both tokens and user profile

Request:

POST /api/auth/login
{
  "login": "user@example.com",
  "password": "SecureP@ss123!"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "uuid-refresh-token",
  "token_type": "Bearer",
  "expires_in": 604800,
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "username": "john",
    "role": "user"
  }
}

Set-Cookie Header:

Set-Cookie: token=eyJhbG...; Max-Age=604800; Path=/; HttpOnly

2. Making Authenticated Requests

Include the JWT token in the Authorization header:

curl -H "Authorization: Bearer <token>" \
  https://api.example.com/api/libraries

The server also checks for the token in the HTTP-only cookie automatically.

3. Token Refresh

When your access token expires (after 7 days), use the refresh token to get a new one:

POST /api/auth/refresh
{
  "refresh_token": "uuid-refresh-token"
}

Response:

{
  "access_token": "new-jwt-token",
  "token_type": "Bearer",
  "expires_in": 604800
}

4. Logout

Revokes the refresh token on the server:

POST /api/auth/logout
{
  "refresh_token": "uuid-refresh-token"
}

Session Expiration Handling

Web Browser Requests

When a user's session expires during page navigation:

  1. Server redirects to /login?session=expired
  2. Login page displays: "Your session has expired. Please log in again to continue."
  3. User re-authenticates and is redirected to their intended destination

API Requests

When an API call receives a 401 Unauthorized response:

{
  "error": "session_expired",
  "message": "Your session has expired. Please log in again."
}

The frontend toast.js interceptor:

  1. Clears invalid tokens from localStorage
  2. Shows an error toast notification
  3. Allows user to re-authenticate

Security Features

  • HTTP-only Cookies: Prevents XSS attacks on token cookies
  • Refresh Token Rotation: New refresh tokens issued on each refresh
  • 7-Day Expiration: Reasonable balance between security and convenience
  • Constants-Based Configuration: Single source of truth for session duration

Token Storage Recommendations

Browser Applications

  • Backend: Automatically manages HTTP-only cookie
  • Frontend: Store tokens in localStorage for API calls

Mobile Applications

  • Store access token in secure storage (Keychain/Keystore)
  • Store refresh token in secure storage
  • Handle 401 responses by prompting user to re-authenticate

Constants Reference

All session durations use constants defined in:

  • internal/handlers/auth.go - SessionDuration, SessionDurationSec
  • internal/handlers/refresh_token.go - SessionDurationSec (mirrored)

Total value: 604800 seconds (7 days × 24 hours × 60 minutes × 60 seconds)