Spotify 授权代码流返回不完整的响应

Posted

技术标签:

【中文标题】Spotify 授权代码流返回不完整的响应【英文标题】:Spotify Authorization Code Flow returns incomplete response 【发布时间】:2019-01-25 22:17:08 【问题描述】:

我有一个 django 服务器,我希望执行 spotify 授权代码流。

这是我创建的一个基本骨架:

用户打开spotify/login url。 SpotifyLoginView 将它们重定向到 https://accounts.spotify.com/authorize 网址。 Spotify 服务器回调到spotify/callback 端点。 SpotifyCallbackViewhttps://accounts.spotify.com/api/token 发出 POST 请求以获取身份验证令牌。

urls.py

urlpatterns = [
    path(
        "spotify/callback", views.SpotifyCallbackView.as_view(), name="spotify callback"
    ),
    path("spotify/login", views.SpotifyLoginView.as_view(), name="spotify login"),
]

views.py

def build_authorize_url(request):
    params = 
        "client_id": "<my client id>",
        "response_type": "code",
        "redirect_uri": request.build_absolute_uri(
            reverse("spotify callback")
        ),
        "scope": " ".join(
            [
                "user-library-read",
                "user-top-read",
                "user-read-recently-played",
                "playlist-read-private",
            ]
        ),
    
    print(params)

    url = (
        furl("https://accounts.spotify.com/authorize")
        .add(params)
        .url
    )
    print(url)

    return url


AUTH_HEADER = 
    "Authorization": "Basic "
    + base64.b64encode(
        "<my client id>:<my client secret>".encode()
    ).decode()



def handle_callback(request):
    code = request.GET["code"]

    response = requests.post(
        "https://accounts.spotify.com/api/token",
        data=
            "grant_type": "client_credentials",
            "code": code,
            "redirect_uri": request.build_absolute_uri(
                reverse("spotify callback")
            ),
        ,
        headers=AUTH_HEADER,
    )

    return response.json()


class SpotifyLoginView(RedirectView):
    query_string = True

    def get_redirect_url(self, *args, **kwargs):
        return build_authorize_url(self.request)


class SpotifyCallbackView(TemplateView):
    template_name = "success.html"

    def get(self, request, *args, **kwargs):
        print(spotify.handle_callback(request))

        return super().get(request, *args, **kwargs)

但是,spotify 返回的响应不包含scoperefresh_token

所以对于这些参数:

'client_id': '&lt;my client id&gt;', 'response_type': 'code', 'redirect_uri': 'http://127.0.0.1:8000/spotify/callback', 'scope': 'user-library-read user-top-read user-read-recently-played playlist-read-private'

翻译成这个网址:

https://accounts.spotify.com/authorize?client_id=&lt;my client id&gt;&amp;response_type=code&amp;redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fspotify%2Fcallback&amp;scope=user-library-read+user-top-read+user-read-recently-played+playlist-read-private

我得到的只是:

'access_token': '&lt;my acess token&gt;', 'token_type': 'Bearer', 'expires_in': 3600, 'scope': ''

虽然docs 建议我应该得到这个:


   "access_token": "NgCXRK...MzYjw",
   "token_type": "Bearer",
   "scope": "user-read-private user-read-email",
   "expires_in": 3600,
   "refresh_token": "NgAagA...Um_SHo"


此外,如果我尝试使用该访问令牌,我会收到 401 HTTP 错误返回。

$ curl -H "Authorization: Bearer <my acess token>" https://api.spotify.com/v1/me



  "error" : 
    "status" : 401,
    "message" : "Unauthorized."
  
   

这是怎么回事?

【问题讨论】:

【参考方案1】:

在向https://accounts.spotify.com/api/token 发出 POST 请求时,您必须使用“authorization_code”作为grant_type 以获得初始访问令牌。在您的handle_callback() 方法中:

 response = requests.post(
    "https://accounts.spotify.com/api/token",
    data=
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": request.build_absolute_uri(
            reverse("spotify callback")
        ),
    ,
    headers=AUTH_HEADER,
)

【讨论】:

以上是关于Spotify 授权代码流返回不完整的响应的主要内容,如果未能解决你的问题,请参考以下文章

Spotify 令牌调用后返回错误网站而不是错误或令牌

Spotify PKCE 授权流程返回“code_verifier 不正确”

服务器返回无效或不完整的 HTTP 响应

Spotify API 授权代码流向我返回 400 错误请求

Spotify Web Api 令牌请求响应 400

使用 Python 的 Spotify API 授权代码流