monorepo/cloud/maplepress-backend/docs/API/refresh-token.md

4.1 KiB

Refresh Token

POST /api/v1/refresh

Obtain a new access token and refresh token using an existing valid refresh token. This endpoint should be called when the access token expires (after 15 minutes) to maintain the user's session without requiring them to log in again.

Authentication: None required (public endpoint, but requires valid refresh token)

Headers:

  • Content-Type: application/json

Request Body:

Field Type Required Description
refresh_token string Yes Valid refresh token from login or previous refresh

Example Request:

curl -X POST http://localhost:8000/api/v1/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Example Response (200 OK):

{
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_email": "john@example.com",
  "user_name": "John Doe",
  "user_role": "user",
  "tenant_id": "650e8400-e29b-41d4-a716-446655440000",
  "session_id": "750e8400-e29b-41d4-a716-446655440000",
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "access_expiry": "2024-10-24T12:30:00Z",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_expiry": "2024-10-31T00:15:00Z",
  "refreshed_at": "2024-10-24T12:15:00Z"
}

Error Responses:

This endpoint returns errors in RFC 9457 (Problem Details for HTTP APIs) format.

Content-Type: application/problem+json

400 Bad Request - Missing refresh token:

{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "Refresh token is required"
}

401 Unauthorized - Invalid or expired refresh token:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid or expired refresh token. Please log in again."
}

401 Unauthorized - Session invalidated:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Session has expired or been invalidated. Please log in again."
}

500 Internal Server Error:

{
  "type": "about:blank",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "Failed to refresh token. Please try again later."
}

Token Refresh Flow:

  1. Initial Authentication: User logs in via /api/v1/login and receives:

    • Access token (expires in 15 minutes)
    • Refresh token (expires in 7 days)
  2. Token Usage: Client uses the access token for API requests

  3. Token Expiration: When access token expires (after 15 minutes):

    • Client detects 401 Unauthorized response
    • Client calls /api/v1/refresh with the refresh token
    • Server validates refresh token and session
    • Server returns new access token and new refresh token
  4. Token Rotation: Both tokens are regenerated on refresh:

    • New access token (valid for 15 minutes from refresh time)
    • New refresh token (valid for 7 days from refresh time)
    • Old tokens become invalid
  5. Session Validation: The refresh token is validated against the active session:

    • If the session has been deleted (e.g., user logged out), refresh will fail
    • If the session has expired (after 14 days of inactivity), refresh will fail
    • This prevents using refresh tokens after logout

Best Practices:

  • Store both access and refresh tokens securely on the client (e.g., secure HTTP-only cookies or encrypted storage)
  • Implement automatic token refresh when access token expires (don't wait for 401 errors)
  • Consider refreshing tokens proactively before expiration (e.g., 1 minute before)
  • Handle refresh failures by redirecting user to login
  • Never share refresh tokens across devices or sessions
  • Clear tokens on logout

Security Notes:

  • Refresh tokens are single-use in practice due to token rotation
  • Each refresh generates a new token pair and invalidates the old one
  • Session validation prevents token reuse after logout (CWE-613)
  • Refresh tokens have a longer lifetime but are still time-limited (7 days)
  • Sessions expire after 14 days of inactivity regardless of token refresh