Skip to content

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.

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 │ │
│ ▼ ▼ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
  1. 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
  2. Local callback server starts

    MiniFy starts a local HTTP server on 127.0.0.1:3000 to receive the OAuth callback. This server only accepts connections from localhost for security.

  3. Browser authorization

    Your default browser opens to Spotify’s authorization page with these parameters:

    • client_id: Your Spotify application ID
    • response_type: code
    • redirect_uri: http://127.0.0.1:3000/callback
    • scope: Requested permissions
    • code_challenge: The SHA-256 hash
    • code_challenge_method: S256
    • state: CSRF protection token
  4. User approves access

    You log in to Spotify (if not already) and approve MiniFy’s access request.

  5. 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.

  6. Token exchange

    MiniFy sends the authorization code along with the original code_verifier to Spotify. Spotify verifies that SHA256(code_verifier) == code_challenge before issuing tokens.

  7. 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

PKCE provides several security advantages for desktop applications:

Traditional OAuthOAuth with PKCE
Requires client secretNo client secret needed
Secret could be extracted from appNothing sensitive to extract
Vulnerable to authorization code interceptionCodes useless without verifier
Single point of failureCryptographically secure

MiniFy requests only the permissions necessary for its features:

ScopePurpose
user-read-playback-stateRead current playback state (track, progress, device)
user-modify-playback-stateControl playback (play, pause, skip, seek)
user-read-currently-playingGet the currently playing track
ScopePurpose
user-top-readAccess top tracks and artists for taste analysis
user-read-recently-playedView recently played tracks for recommendations
user-library-readRead saved tracks count
playlist-read-privateAccess private playlists
┌──────────────────────────────────────────────────────────────┐
│ 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
  • Validity: Long-lived (months) unless revoked
  • Rotation: Spotify may issue a new refresh token with each use
  • Storage: Securely stored in OS keyring

Credential Manager (Windows Credential Manager)

Target: minify:access_token
Target: minify:refresh_token
Target: minify:token_expiry
Target: minify:spotify_client_id

View with: Control Panel → User Accounts → Credential Manager

MiniFy supports two ways to configure the Spotify Client ID:

Official MiniFy releases have a Client ID embedded at build time. Users don’t need to configure anything.

For development or self-built versions, MiniFy walks you through this on the setup screen:

  1. Go to Spotify Developer Dashboard
  2. Create a new application (any name)
  3. Add the exact Redirect URI shown on the setup screen — http://127.0.0.1:3000/callback — and save. Use the Copy button so it matches character for character.
  4. Copy the Client ID from the app’s settings
  5. Paste it into MiniFy’s setup screen and click Connect to Spotify

To disconnect MiniFy from your Spotify account:

  1. Open Settings (right-click → Settings)
  2. Navigate to “Connections”
  3. Click “Disconnect from Spotify”
  4. 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

You can also revoke MiniFy’s access from Spotify:

  1. Go to Spotify Account Apps
  2. Find MiniFy in the list
  3. Click “Remove Access”

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.

  • 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

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

Tokens are stored using OS-level encryption:

  • Windows: DPAPI (Data Protection API)
  • macOS: AES-256 via Keychain
  • Linux: Encryption depends on Secret Service implementation

Another application is using port 3000. Either:

  • Close the conflicting application
  • Wait for MiniFy’s timeout (5 minutes) and try again

This occurs when:

  • You have old browser tabs open from previous auth attempts
  • Solution: Close all Spotify auth tabs and try again

Your refresh token may have been revoked:

  1. Clear credentials: Settings → Connections → Disconnect
  2. Re-authenticate with Spotify

Your Spotify app configuration doesn’t include the callback URL:

  1. Go to Spotify Developer Dashboard
  2. Edit your application
  3. Add http://127.0.0.1:3000/callback to Redirect URIs
  4. Save changes

MiniFy couldn’t launch your default browser:

  • Ensure you have a default browser configured
  • Try manually opening the auth URL from the error message
Terminal window
# Embed Client ID at build time
SPOTIFY_CLIENT_ID=your_client_id pnpm desktop:build
Terminal window
# Clear all stored credentials for testing
pnpm desktop:clear

The OAuth callback server automatically shuts down after:

  • 5 minutes of inactivity
  • Successful token exchange
  • User cancellation