代码之家  ›  专栏  ›  技术社区  ›  Dev Aggarwal

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

  •  0
  • Dev Aggarwal  · 技术社区  · 7 年前

    以下是我创建的基本骨架:

    • 用户打开 spotify/login 网址。
    • 这个 SpotifyLoginView https://accounts.spotify.com/authorize 网址。
    • spotify服务器回调到 spotify/callback 终点。
    • 这个 SpotifyCallbackView https://accounts.spotify.com/api/token 以获取身份验证令牌。

    网址.py

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

    视图.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)
    

    scope refresh_token !

    所以对于这些参数:

    {'client_id': '<my client id>', '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=<my client id>&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fspotify%2Fcallback&scope=user-library-read+user-top-read+user-read-recently-played+playlist-read-private

    我得到的是:

    {'access_token': '<my acess token>', '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 回复  |  直到 7 年前
        1
  •  3
  •   zypox    7 年前

    您必须使用“授权码”作为 grant_type 在向 https://accounts.spotify.com/api/token 以获取初始访问令牌。在你的 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,
    )