【问题标题】:Why do I keep getting a 400 Bad Request Error when exchanging code for access token from Spotify API?从 Spotify API 交换访问令牌的代码时,为什么我不断收到 400 错误请求错误?
【发布时间】:2021-05-29 19:04:52
【问题描述】:
import requests
import base64
from secrets import USER_CLIENT_ID, USER_CLIENT_SECRET, USER_REDIRECT_URI

# using OAuth we create a link to redirect user to their spotify account
def create_oauth_link():
    params = {
        "client_id": USER_CLIENT_ID,
        "response_type": "code",
        "redirect_uri": USER_REDIRECT_URI,
        "scope": "user-read-private user-read-email"
    }
    endpoint = "https://accounts.spotify.com/authorize"
    response = requests.get(endpoint, params=params)
    url = response.url
    return url

# authorization process to exchange code for token
def exchange_code_token(code=None):
    message = f"{USER_CLIENT_ID}:{USER_CLIENT_SECRET}"
    messageBytes = message.encode("ascii")
    base64Bytes = base64.b64encode(messageBytes)
    base64Message = base64Bytes.decode("ascii")
    headers = {'Authorization': f'Basic {base64Message}'}
    params = {
        'grant_type': "authorization_code",
        "code": code,
        "redirect_uri": USER_REDIRECT_URI,
        #"client_id": USER_CLIENT_ID,
        #"client_secret": USER_CLIENT_SECRET,
        }
    endpoint = "https://accounts.spotify.com/api/token"
    response = requests.post(endpoint, params=params, headers=headers)
    print(response.reason)

link = create_oauth_link()
print(f"Follow the link to start the authentication with Spotify: {link}")
code = input("Spotify Code: ")
exchange_code_token(code)

我正在成功生成代码,但是在尝试将其交换为访问令牌时一切都出错了。我收到了错误的请求响应。 我已尝试根据 Spotify 的文档以及通过 base64 编码通过请求参数传递 client_id 和 client_secret,但似乎没有任何效果。 可能是什么问题?

【问题讨论】:

    标签: python api post python-requests spotify


    【解决方案1】:

    client_id 和 client_secret 通常不是在一个 OAuth 请求中吗? 此外,有时您需要一个本地 token.txt,它会在您通过网站请求手动登录后创建。这个.txt。包含一个额外的访问令牌!那就是您的问题所在。此代码应将您重定向到一个 spotify 页面(如果您在 spotify 中创建了您的应用程序),并且应该要求您采取行动(点击按钮或类似的东西)而不是您的 token.txt。将在您的文件夹中创建。如果不是自己创建。

    这是我曾经写过的东西,用来创建我自己的 Top 100 音乐列表,从网站上抓取并在 spotify 中搜索。邀请您复制 OAuth 策略:

    import spotipy
    from spotipy.oauth2 import SpotifyOAuth
    import requests
    from bs4 import BeautifulSoup
    
    client_id = "your id"
    client_secret = "your secret"
    time_travel = input("Which year you want to travel to? Insert a format of YYYY-MM-DD: ")
    
    response = requests.get(url=f"https://www.billboard.com/charts/hot-100/{time_travel}")
    time_travel = time_travel.split("-")[0]
    soup = BeautifulSoup(response.text, "lxml")
    
    interpret = soup.find_all(name="span",
                              class_="chart-element__information__artist text--truncate color--secondary")
    
    title = soup.find_all(name="span",
                          class_="chart-element__information__song text--truncate color--primary")
    
    top_100_interpret = [element.string for element in interpret]
    top_100_title = [element.string for element in title]
    
    sp = spotipy.Spotify(
            auth_manager=SpotifyOAuth(
            scope="playlist-modify-private playlist-modify-public",
            redirect_uri="http://localhost:8888/callback",
            client_id=client_id,
            client_secret=client_secret,
            show_dialog=True,
            cache_path="token.txt")
    )
    
    uris_artists = []
    found_spotify_tracks = []
    
    #search artist
    #for artist in top_100_interpret[:10]:
    for artist in top_100_interpret:
        try:
            result = sp.search(q=f"artist:{artist} year:{time_travel}", type="artist")
            uri_artist = result["artists"]["items"][0]["uri"]
    
            #search top ten 10 of artist
            tracks = [sp.artist_top_tracks(uri_artist, country="US")["tracks"][_]["name"] for _ in range(10)]
            tracks_uri = [sp.artist_top_tracks(uri_artist, country="US")["tracks"][_]["uri"] for _ in range(10)]
            found_track = [track in top_100_title for track in tracks]
            index_found_spotify = found_track.index(True)
        except:
            uri_artist = ""
            tracks = ""
            print("Artist or Song not found")
        else:
            found_spotify_tracks.append(tracks_uri[index_found_spotify])
    
    
    def create_playlist() -> str:
        playlist_name = f"Top 100 in {time_travel}"
        user_id = sp.current_user()["id"]
        playlist_dict = sp.user_playlist_create(user_id,
                             playlist_name,
                             public=True,
                             collaborative=False,
                             description='Auto generated Playlist with Python, if track found')
        return playlist_dict
    
    
    def add_to_playlist(id_name: str, uris: list) -> None:
        sp.playlist_add_items(id_name, uris, position=None)
    
    
    playlist_dict = create_playlist()
    add_to_playlist(playlist_dict["uri"], found_spotify_tracks)
    

    【讨论】:

    • 谢谢! Spotipy 暂时解决了我的问题,但是我想知道他们如何传递/格式化正文和标头参数以将代码交换为令牌。
    • developer.spotify.com/documentation/general/guides/… 采取 4 的第一个自动化工作流程。访问令牌通常是一个所谓的不记名令牌,它位于 api 请求的标头中,但是您在标头中写道: headers = {'Authorization ': f'Basic {base64Message}'},通常需要一个“Bearer”
    • 所以我终于弄明白了,通过主体参数或标头 base64 方法传递客户端凭据不是问题,错误出现在我的 POST 请求中。我没有将它作为 json() 对象传递。 s_response = requests.post(s_endpoint, data=code_params).json()
    猜你喜欢
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2012-09-06
    • 2012-06-29
    • 1970-01-01
    • 2012-10-04
    相关资源
    最近更新 更多