You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spotify API授权码流(Authorization Code Flow)实现失败:invalid_grant错误及授权跳转异常问题排查

Fixing Your Spotify Authorization Code Flow Issues

Let's break down what's going wrong here and fix your Spotify authorization code flow step by step—this is a common gotcha for beginners, so don't worry!

1. Why You're Not Seeing the Authorization Page or Redirect

You're passing critical authorization parameters (client_id, response_type, etc.) in the request headers, but Spotify's authorization endpoint requires these values to be sent as URL query parameters instead. The server isn't recognizing your request as a valid authorization prompt, so it returns a generic 200 response instead of redirecting to the login/permission screen.

2. Why Your Authorization Code is Invalid

You're trying to use the full requests.get response object as your authorization code, which is completely incorrect. The actual authorization code is a string that Spotify sends to your specified redirect_uri after the user logs in and approves permissions—it will appear as a query parameter in the URL of the page you're redirected to (e.g., https://your-redirect-uri.com?code=VALID_AUTH_CODE_HERE).

Corrected Code & Step-by-Step Walkthrough

Here's a revised version of your class with proper authorization flow handling, plus instructions on how to use it:

import requests
import base64
import datetime

class SpotifyAPIFlow(object):
    access_token = None
    access_token_expires = datetime.datetime.now()
    access_token_did_expire = True
    client_id = None
    client_secret = None
    token_url = "https://accounts.spotify.com/api/token"
    auth_url = "https://accounts.spotify.com/authorize"

    def __init__(self, client_id, client_secret, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.client_id = client_id
        self.client_secret = client_secret

    def get_client_credentials(self):
        """Return a base64 encoded client ID/secret string"""
        if self.client_secret is None or self.client_id is None:
            raise Exception("You must set client ID and client secret first!\n")
        client_creds = f"{self.client_id}:{self.client_secret}"
        client_creds_b64 = base64.b64encode(client_creds.encode())
        return client_creds_b64.decode()

    def get_token_headers(self):
        client_creds_b64 = self.get_client_credentials()
        return {"Authorization": f"Basic {client_creds_b64}"}

    def generate_auth_url(self):
        """Build a valid authorization URL to send the user to"""
        auth_params = {
            'client_id': self.client_id,
            'response_type': 'code',
            'redirect_uri': 'https://open.spotify.com/collection/playlists',  # Must match your Spotify Dashboard setting!
            'scope': 'user-top-read'
        }
        # Automatically format parameters into a valid URL
        return requests.Request('GET', self.auth_url, params=auth_params).prepare().url

    def exchange_code_for_token(self, auth_code):
        """Exchange a valid authorization code for an access token"""
        token_headers = self.get_token_headers()
        payload = {
            'grant_type': 'authorization_code',
            'code': auth_code,
            'redirect_uri': 'https://open.spotify.com/collection/playlists',  # Exact match to the auth URL's redirect URI
        }
        access_token_request = requests.post(url=self.token_url, data=payload, headers=token_headers)
        
        if access_token_request.status_code == 200:
            response_data = access_token_request.json()
            self.access_token = response_data['access_token']
            expires_in = response_data['expires_in']
            self.access_token_expires = datetime.datetime.now() + datetime.timedelta(seconds=expires_in)
            self.access_token_did_expire = self.access_token_expires < datetime.datetime.now()
            return response_data
        else:
            print(f"Token exchange failed: {access_token_request.json()}")
            return None

How to Use This Code:

  • Step 1: Initialize the class with your Spotify client ID and secret (from the Spotify Developer Dashboard):
    spotify_auth = SpotifyAPIFlow("your_client_id", "your_client_secret")
    
  • Step 2: Generate the authorization URL and open it in your browser:
    auth_url = spotify_auth.generate_auth_url()
    print("Open this URL in your browser to authorize:", auth_url)
    
  • Step 3: After logging in and approving permissions, Spotify will redirect you to your redirect_uri. Copy the code parameter from the end of the URL (e.g., the string after ?code=).
  • Step 4: Exchange the code for an access token:
    user_auth_code = input("Paste the authorization code here: ")
    token_data = spotify_auth.exchange_code_for_token(user_auth_code)
    print("Success! Token data:", token_data)
    

Critical Reminders:

  • Redirect URI Must Match: The redirect_uri in your code must be exactly the same as the one you added to your app in the Spotify Developer Dashboard (including capitalization and trailing slashes). Mismatches will cause errors.
  • Authorization Codes Are Single-Use: Each code can only be exchanged once—if you get an invalid_grant error, generate a new authorization URL and get a fresh code.
  • User Interaction is Required: The authorization code flow is designed to require user consent, so you can't fully automate this process without setting up a local server to capture the redirect (an advanced step for later).

内容的提问来源于stack exchange,提问作者Calin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:04:10