Authentication
Authentication
MiniFy uses Spotify’s OAuth 2.0 authentication to securely access your Spotify account. This page provides a comprehensive explanation of the authentication process, security measures, and troubleshooting guidance.
Overview
MiniFy implements the Authorization Code Flow with PKCE (Proof Key for Code Exchange), which is the most secure OAuth flow for public clients like desktop applications that cannot securely store a client secret.
┌─────────────────────────────────────────────────────────────────────────────┐│ OAuth 2.0 PKCE Authentication Flow │├─────────────────────────────────────────────────────────────────────────────┤│ ││ ┌──────────┐ ┌──────────────┐ ││ │ MiniFy │ │ Spotify │ ││ │ Desktop │ │ Servers │ ││ └────┬─────┘ └──────┬───────┘ ││ │ │ ││ │ 1. Generate code_verifier (64 random chars) │ ││ │ 2. Create code_challenge = SHA256(code_verifier) │ ││ │ 3. Store state nonce (CSRF protection) │ ││ │ │ ││ │ ─────────────── Authorization Request ─────────────────▶│ ││ │ (code_challenge, state) │ ││ │ │ ││ │ ┌────────────────────┐ │ ││ │ │ User logs in & │ │ ││ │ │ approves access │ │ ││ │ └────────────────────┘ │ ││ │ │ ││ │ ◀────────────── Redirect to localhost:3000 ────────────│ ││ │ (authorization_code, state) │ ││ │ │ ││ │ 4. Verify state matches (CSRF check) │ ││ │ │ ││ │ ─────────────── Token Exchange Request ────────────────▶│ ││ │ (code + code_verifier) │ ││ │ │ ││ │ 5. Server verifies SHA256(code_verifier) │ ││ │ matches original code_challenge │ ││ │ │ ││ │ ◀──────────────── Access & Refresh Tokens ─────────────│ ││ │ │ ││ │ 6. Store tokens securely in OS keyring │ ││ ▼ ▼ ││ │└─────────────────────────────────────────────────────────────────────────────┘Detailed Authentication Steps
-
User initiates authentication
When you click “Connect to Spotify”, MiniFy generates cryptographic values:
- Code Verifier: A 64-character random string using URL-safe characters
- Code Challenge: SHA-256 hash of the verifier, base64-URL encoded
- State Nonce: A random 32-character hex string for CSRF protection
-
Local callback server starts
MiniFy starts a local HTTP server on
127.0.0.1:3000to receive the OAuth callback. This server only accepts connections from localhost for security. -
Browser authorization
Your default browser opens to Spotify’s authorization page with these parameters:
client_id: Your Spotify application IDresponse_type:coderedirect_uri:http://127.0.0.1:3000/callbackscope: Requested permissionscode_challenge: The SHA-256 hashcode_challenge_method:S256state: CSRF protection token
-
User approves access
You log in to Spotify (if not already) and approve MiniFy’s access request.
-
Callback handling
Spotify redirects to the local callback URL with:
code: Authorization code (one-time use)state: Must match the original state nonce
MiniFy validates the state parameter to prevent CSRF attacks.
-
Token exchange
MiniFy sends the authorization code along with the original code_verifier to Spotify. Spotify verifies that
SHA256(code_verifier) == code_challengebefore issuing tokens. -
Secure storage
Tokens are stored in the operating system’s secure credential manager:
- Access token (short-lived, ~1 hour)
- Refresh token (long-lived)
- Token expiry timestamp
Why PKCE?
PKCE provides several security advantages for desktop applications:
| Traditional OAuth | OAuth with PKCE |
|---|---|
| Requires client secret | No client secret needed |
| Secret could be extracted from app | Nothing sensitive to extract |
| Vulnerable to authorization code interception | Codes useless without verifier |
| Single point of failure | Cryptographically secure |
Required Permissions (Scopes)
MiniFy requests only the permissions necessary for its features:
Core Playback
| Scope | Purpose |
|---|---|
user-read-playback-state | Read current playback state (track, progress, device) |
user-modify-playback-state | Control playback (play, pause, skip, seek) |
user-read-currently-playing | Get the currently playing track |
AI DJ Features
| Scope | Purpose |
|---|---|
user-top-read | Access top tracks and artists for taste analysis |
user-read-recently-played | View recently played tracks for recommendations |
user-library-read | Read saved tracks count |
playlist-read-private | Access private playlists |
Token Lifecycle
Access Token
┌──────────────────────────────────────────────────────────────┐│ Access Token Lifecycle │├──────────────────────────────────────────────────────────────┤│ ││ ┌─────────────┐ ││ │ Token │ ││ │ Issued │────▶ Valid for ~1 hour ││ └─────────────┘ ││ │ ││ │ Used for all Spotify API requests ││ │ ││ ▼ ││ ┌─────────────┐ ││ │ 5 minutes │ ││ │ before │────▶ Background refresh task triggers ││ │ expiry │ ││ └─────────────┘ ││ │ ││ ▼ ││ ┌─────────────┐ ││ │ New token │ ││ │ issued │────▶ Seamlessly replaces old token ││ └─────────────┘ ││ │└──────────────────────────────────────────────────────────────┘- Validity: ~1 hour (set by Spotify)
- Auto-refresh: MiniFy runs a background task every 5 minutes that checks if the token will expire within 5 minutes and proactively refreshes it
- Retry on 401: If a request fails with 401 Unauthorized, MiniFy automatically refreshes the token and retries the request
Refresh Token
- Validity: Long-lived (months) unless revoked
- Rotation: Spotify may issue a new refresh token with each use
- Storage: Securely stored in OS keyring
Token Storage Locations
Credential Manager (Windows Credential Manager)
Target: minify:access_tokenTarget: minify:refresh_tokenTarget: minify:token_expiryTarget: minify:spotify_client_idView with: Control Panel → User Accounts → Credential Manager
Keychain (Keychain Access.app)
Service: minifyAccount: access_tokenAccount: refresh_tokenAccount: token_expiryAccount: spotify_client_idView with: Applications → Utilities → Keychain Access
Secret Service (GNOME Keyring or KDE Wallet)
Collection: Default keyringLabel: minify:access_tokenLabel: minify:refresh_tokenLabel: minify:token_expiryLabel: minify:spotify_client_idView with: Seahorse (GNOME) or KWallet Manager (KDE)
Client ID Configuration
MiniFy supports two ways to configure the Spotify Client ID:
1. Embedded (Recommended for end users)
Official MiniFy releases have a Client ID embedded at build time. Users don’t need to configure anything.
2. User-provided
For development or self-built versions:
- Go to Spotify Developer Dashboard
- Create a new application
- Add
http://127.0.0.1:3000/callbackto Redirect URIs - Copy the Client ID
- Enter it in MiniFy’s setup screen
Disconnecting
To disconnect MiniFy from your Spotify account:
From MiniFy
- Open Settings (right-click → Settings)
- Navigate to “Connections”
- Click “Disconnect from Spotify”
- Confirm the disconnection
This will:
- Delete all tokens from the OS keyring
- Clear the stored Client ID (if user-provided)
- Reset MiniFy to the initial setup state
From Spotify
You can also revoke MiniFy’s access from Spotify:
- Go to Spotify Account Apps
- Find MiniFy in the list
- Click “Remove Access”
Security Measures
CSRF Protection
Every OAuth flow generates a unique state nonce. The callback validates that the returned state matches the expected value, preventing cross-site request forgery attacks.
Code Verifier Security
- Generated using cryptographically secure random number generator
- Contains 64 characters from the URL-safe alphabet
- Never transmitted over the network (only the hash is sent)
- Cleared from memory after token exchange
Localhost-only Callback
The callback server binds exclusively to 127.0.0.1:3000, ensuring:
- No external network access
- No DNS rebinding attacks
- Callback only works on the local machine
Token Encryption
Tokens are stored using OS-level encryption:
- Windows: DPAPI (Data Protection API)
- macOS: AES-256 via Keychain
- Linux: Encryption depends on Secret Service implementation
Troubleshooting
”Port 3000 already in use”
Another application is using port 3000. Either:
- Close the conflicting application
- Wait for MiniFy’s timeout (5 minutes) and try again
”State mismatch” error
This occurs when:
- You have old browser tabs open from previous auth attempts
- Solution: Close all Spotify auth tabs and try again
Token refresh fails repeatedly
Your refresh token may have been revoked:
- Clear credentials: Settings → Connections → Disconnect
- Re-authenticate with Spotify
”Invalid redirect URI”
Your Spotify app configuration doesn’t include the callback URL:
- Go to Spotify Developer Dashboard
- Edit your application
- Add
http://127.0.0.1:3000/callbackto Redirect URIs - Save changes
Browser doesn’t open
MiniFy couldn’t launch your default browser:
- Ensure you have a default browser configured
- Try manually opening the auth URL from the error message
For Developers
Environment Variables
# Embed Client ID at build timeSPOTIFY_CLIENT_ID=your_client_id pnpm desktop:buildTesting Authentication
# Clear all stored credentials for testingpnpm desktop:clearOAuth Flow Timeout
The OAuth callback server automatically shuts down after:
- 5 minutes of inactivity
- Successful token exchange
- User cancellation