【问题标题】:auth_head = {"Authorization": "Bearer {}".format(response["access_token"])} KeyError: 'access_token'auth_head = {"Authorization": "Bearer {}".format(response["access_token"])} KeyError: 'access_token'
【发布时间】:2020-07-08 18:14:32
【问题描述】:

我制作了一个 Python 程序,可以将音乐从 YouTube 播放列表传输到您的 Spotify 帐户,我想将它变成一个具有简单 UI 的网络应用程序,这样人们就可以登录到他们的 yt/spotify 帐户,而无需从命令行。我使用 Flask 来制作界面,当我在我的YouTubetoSpotify 文件中手动输入登录信息时它可以工作,现在我正在努力在 UI 顶部实现Oauth2,以便当用户单击其中一个登录按钮,它会将它们定向到相应的身份验证页面(现在我正在处理 Spotify 登录)。

经过一番调试,似乎正确获取了client id和secret,但是当它们用于获取token时(在flask_spotify_auth中的getToken函数中),post请求返回错误。这是完整的错误消息,以及我的所有文件。

{'error': 'invalid_client'}
[2020-07-08 14:09:13,121] ERROR in app: Exception on /callback/ [GET]
Traceback (most recent call last):
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\jared\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:/Users/jared/codingProjects/python_projects/Mixify/app.py", line 30, in upload
    startup.getUserToken(request.args['code'])
  File "C:\Users\jared\codingProjects\python_projects\Mixify\startup.py", line 29, in getUserToken
    TOKEN_DATA = getToken(code, CLIENT_ID, CLIENT_SECRET, "{}:{}/callback/".format(CALLBACK_URL, PORT))
  File "C:\Users\jared\codingProjects\python_projects\Mixify\flask_spotify_auth.py", line 33, in getToken
    return handleToken(json.loads(post.text))
  File "C:\Users\jared\codingProjects\python_projects\Mixify\flask_spotify_auth.py", line 38, in handleToken
    auth_head = {"Authorization": "Bearer {}".format(response["access_token"])}
KeyError: 'access_token'
127.0.0.1 - - [08/Jul/2020 14:09:13] "GET /callback/?code=AQA9preCSj1r87JMxXt5XUBwC6LT-ZQM_By2NYTcdhi7wgUIwQKO6Q5Cm7ChcKdJ_Rd3IkCxdTKw7RlI4EYZNIZrp9RpZfOd1rXeE8v_2tY3A0Q-RKqP21jmRHMFOdTV4z1Lj6lQ1WXcOmbL5eP614ps8TfDPOzBwOfHMvILr-y3HsB30RlYJ6X2XQLUb5p3347YIsx4lfcja9unWa1SjyXw7pbYdOA HTTP/1.1" 500 -

app.py

# Jared Tewodros
# jmt5rg

from flask import *
import YoutubeToSpotify
import startup

app = Flask(__name__)


# @app.errorhandler(404)
# def page_not_found(e):
#     return render_template('404.html'), 404


# home page
# @app.route("/")
# def upload():
#     return render_template("file_upload.html")


@app.route("/")
def index():
    response = startup.getUser()
    return redirect(response)


@app.route('/callback/', methods=["GET", "POST"])
def upload():
    startup.getUserToken(request.args['code'])
    return render_template("file_upload.html")


# and that's all folks
@app.route("/convert", methods=["POST"])
def success():
    global yt_list
    global sp_list
    global desc
    yt_list = request.form['ytPL']
    sp_list = request.form['spPL']
    desc = request.form['desc']
    cp = YoutubeToSpotify.YouTubePlaylist()
    cp.add_song_to_playlist(yt_list, sp_list, desc)
    return render_template("success.html")


if __name__ == "__main__":
    app.run()

startup.py

# Jared Tewodros
# jmt5rg

from flask_spotify_auth import getAuth, refreshAuth, getToken

# Add your client ID
CLIENT_ID = "53754c6314ec4175b8dc3d23c864cb5a"

# aDD YOUR CLIENT SECRET FROM SPOTIFY
CLIENT_SECRET = "6677e13f615b4cfda88371b233b9ae08"

# Port and callback url can be changed or ledt to localhost:5000
PORT = "5000"
CALLBACK_URL = "http://localhost"

# Add needed scope from spotify user
# SCOPE = "streaming user-read-birthdate user-read-email user-read-private"
SCOPE = "user-read-email user-read-private"
# token_data will hold authentication header with access code, the allowed scopes, and the refresh countdown
TOKEN_DATA = []


def getUser():
    return getAuth(CLIENT_ID, "{}:{}/callback/".format(CALLBACK_URL, PORT), SCOPE)


def getUserToken(code):
    global TOKEN_DATA
    TOKEN_DATA = getToken(code, CLIENT_ID, CLIENT_SECRET, "{}:{}/callback/".format(CALLBACK_URL, PORT))


def refreshToken(time):
    time.sleep(time)
    TOKEN_DATA = refreshAuth()


def getAccessToken():
    return TOKEN

flask_spotify_auth.py

# Jared Tewodros
# jmt5rg

import base64, json, requests

SPOTIFY_URL_AUTH = 'https://accounts.spotify.com/authorize/?'
SPOTIFY_URL_TOKEN = 'https://accounts.spotify.com/api/token/'
RESPONSE_TYPE = 'code'
HEADER = 'application/x-www-form-urlencoded'
REFRESH_TOKEN = ''


def getAuth(client_id, redirect_uri, scope):
    data = "{}client_id={}&response_type=code&redirect_uri={}&scope={}".format(SPOTIFY_URL_AUTH, client_id,
                                                                               redirect_uri, scope)
    return data


def getToken(code, client_id, client_secret, redirect_uri):
    body = {
        "grant_type": 'authorization_code',
        "code": code,
        "redirect_uri": redirect_uri,
        "client_id": client_id,
        "client_secret": client_secret
    }
    iden = "{}:{}".format(client_id, client_secret)
    iden_bytes = iden.encode('ascii')
    encoded = base64.b64encode(iden_bytes)
    headers = {"Content-Type": HEADER, "Authorization": "Basic {}".format(encoded)}

    post = requests.post(SPOTIFY_URL_TOKEN, params=body, headers=headers)
    return handleToken(json.loads(post.text))


def handleToken(response):
    print(response)
    auth_head = {"Authorization": "Bearer {}".format(response["access_token"])}
    REFRESH_TOKEN = response["refresh_token"]
    return [response["access_token"], auth_head, response["scope"], response["expires_in"]]


def refreshAuth():
    body = {
        "grant_type": "refresh_token",
        "refresh_token": REFRESH_TOKEN
    }

    post_refresh = requests.post(SPOTIFY_URL_TOKEN, data=body, headers=HEADER)
    p_back = json.dumps(post_refresh.text)

    return handleToken(p_back)

【问题讨论】:

    标签: python flask python-requests spotify


    【解决方案1】:

    您打印的响应是

    {'error': 'invalid_client'}
    

    您在对 spotify API 进行身份验证时似乎出错了。 您的错误KeyError: 'access_token' 来自于此。响应中确实没有access_token 键。

    您必须调整您的 handleToken 方法来处理不同的错误代码。

    他们都被描述为here


    这里是错误的描述invalid_client

    因为它是一个发布请求。 您的 body 变量应该在 data 属性中传递,而不是 params

    因为params 会将您的正文作为 URL 的查询字符串发送

    post = requests.post(SPOTIFY_URL_TOKEN, data=body, headers=headers)
    

    PS : 不要在上面发布您的 CLIENT_IDCLIENT_SECRET所以这些是私人信息。

    【讨论】:

      猜你喜欢
      • 2021-05-03
      • 1970-01-01
      • 2019-10-15
      • 2020-04-10
      • 2018-01-07
      • 1970-01-01
      • 2021-04-28
      • 2019-05-13
      • 2018-01-02
      相关资源
      最近更新 更多