Spotify OAuth Flow
Relevant source files
The following files were used as context for generating this wiki page:
The Spotify OAuth Flow in MoodTune facilitates secure authorization between the application and the Spotify Web API. This system allows the backend to act on behalf of the user to fetch profile information, playlists, and audio features required for mood analysis. The implementation utilizes a state-based CSRF protection mechanism and automated token management to ensure persistent connectivity.
The flow is integrated with the project's Supabase authentication system, requiring a valid Supabase JWT for initial authorization requests and mapping Spotify tokens to specific Supabase user IDs.
Sources: app/api/v1/spotify.py:16-95, app/services/spotify_auth.py:23-53, TEST_PLAN.md:12-25
OAuth Architecture and Data Flow
The architecture follows the standard Authorization Code Flow. It involves three primary stages: generating an authorization URL, handling the callback from Spotify, and persisting/refreshing tokens for subsequent API calls.
Authorization Initiation
The process begins when an authenticated user requests an authorization URL. The backend generates a secure, random state parameter to prevent Cross-Site Request Forgery (CSRF). This state is persisted in the spotify_oauth_states table with a 10-minute Time-To-Live (TTL).
Sources: app/api/v1/spotify.py:19-33, db/spotify_oauth_states.sql:2-7
Sequence Diagram: Authentication and Callback
The following diagram illustrates the interaction between the User, Backend API, Spotify, and the Database during the OAuth handshake.
Component Breakdown
Database Schema
The system relies on two primary tables to manage the OAuth lifecycle and persistence.
| Table Name | Field | Type | Description |
|---|---|---|---|
spotify_oauth_states | state | TEXT (PK) | Unique CSRF token. |
user_id | UUID | References auth.users(id). | |
expires_at | TIMESTAMPTZ | 10-minute expiry for the state. | |
spotify_connections | access_token | TEXT | Current token for API requests. |
refresh_token | TEXT | Token used to fetch new access tokens. | |
expires_at | TIMESTAMPTZ | Absolute time of access token expiry. |
Sources: db/spotify_oauth_states.sql:2-7, app/crud/spotify.py:38-52, TEST_PLAN.md:465-475
Core Service Functions
The business logic is encapsulated within app/services/spotify_auth.py and app/services/spotify_api.py.
generate_authorize_url(state): Constructs the Spotify URL usingSPOTIFY_CLIENT_ID,SPOTIFY_REDIRECT_URI, andSPOTIFY_SCOPES.exchange_code_for_tokens(code): Performs a POST request toaccounts.spotify.com/api/tokenusing basic auth (Client ID and Secret).get_valid_spotify_token(user_id): A critical wrapper that checks the database for an existing connection. Ifexpires_athas passed, it automatically callsrefresh_access_tokenand updates the database before returning a usable token.
Sources: app/services/spotify_auth.py:23-53, app/services/spotify_api.py:12-70
Token Management and Refresh Logic
MoodTune implements automatic token refreshing to ensure uninterrupted service for playlist and song analysis.
API Endpoints for OAuth & Connection
| Endpoint | Method | Description |
|---|---|---|
/spotify/authorize | GET | Initiates flow; returns Spotify URL and state. |
/spotify/callback | GET | Handles Spotify redirect; exchanges code for tokens. |
/spotify/status | GET | Returns boolean connected status for current user. |
/spotify/disconnect | POST | Deletes the user's entry from spotify_connections. |
Sources: app/api/v1/spotify.py:19-145, TEST_PLAN.md:73-205
Security Implementation
The flow incorporates several security best practices:
- CSRF Protection: The
stateparameter is mandatory. If thestateprovided in the callback does not exist in thespotify_oauth_statestable, the connection is rejected. - Single-Use State: Upon successful verification, the
staterecord is immediately deleted from the database. - User Isolation: The
get_valid_spotify_tokenfunction scopes connection lookups to theuser_idderived from the Supabase JWT, preventing cross-user data access. - Backend Credentials: Spotify Client Secrets are handled exclusively server-side during the token exchange and refresh processes.
Sources: app/api/v1/spotify.py:44-55, db/spotify_oauth_states.sql:2-7, app/services/spotify_auth.py:40-58
The Spotify OAuth flow serves as the foundation for the application's integration features, ensuring that user tokens are securely stored and transparently refreshed to support the core song and playlist analysis services.