Spotify - 使用隐式流获取和更改用户数据

Spotify - get and change user data with Implicit Flow

我正在尝试为 Spotify api 实现一个简单的 python 客户端。根据Spotify's Authorization Guide,应用可以通过两种方式授权:

  • App Authorization: Spotify authorizes your app to access the Spotify Platform (APIs, SDKs and Widgets).
  • User Authorization: Spotify, as well as the user, grant your app permission to access and/or modify the user’s own data. For information about User Authentication, see User Authentication with OAuth 2.0. Calls to the Spotify Web API require authorization by your application user. To get that authorization, your application generates a call to the Spotify Accounts Service /authorize endpoint, passing along a list of the scopes for which access permission is sought.

客户凭证

我第一次尝试使用 oauth2 module from Spotipy 的应用程序授权,因为它不需要传递令牌,而只需要属于应用程序开发人员的客户端 ID 和客户端密码。

client.py

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

class SpotifyWrapper(spotipy.Spotify):
    def category_playlists(self, category, limit=50, offset=0):
        return self._get('browse/categories/%s/playlists' % category,
                         limit=limit,
                         offset=offset)

def get_api_client():
    # create a client authentication request
    client_cred = SpotifyClientCredentials(
        client_id=DevelopmentConfig.SPOTIFY_CLIENT_ID,
        client_secret=DevelopmentConfig.SPOTIFY_CLIENT_SECRET
    )

    # create a spotify client with a bearer token,
    # dynamically re-created if necessary
    return SpotifyWrapper(auth=client_cred.get_access_token())

然后我会在这里导入并声明它:

spotify_utilities.py

from app.resources.spotify.client import get_api_client

sp = get_api_client()

为了发出请求并获取用户播放列表,请像这样传递它:

def get_user_playlist(username, sp):
    ids=[]
    playlists = sp.user_playlists(username)
    for playlist in playlists['items']:
        ids.append(playlist['id'])
        print("Name: {}, Number of songs: {}, Playlist ID: {} ".
              format(playlist['name'].encode('utf8'),
                     playlist['tracks']['total'],
                     playlist['id']))
    return ids

这有效并且将获取用户内容,其中用户是应用开发者


隐式流

现在我想转到隐式流程,应用程序会询问任何使用访问权限和范围的用户,为此需要令牌。

一旦我使用 Javascript 获取令牌,我知道我可以使用它通过简单的请求获取访问 API 的用户数据:

GET_USER_PROFILE_ENDPOINT = 'https://api.spotify.com/v1/users/{user_id}'
GET_USER_PLAYLISTS_ENDPOINT = 'https://api.spotify.com/v1/users/{user_id}/playlists'

def get_user_profile(token, user_id):
    url = GET_USER_PROFILE_ENDPOINT.format(id=user_id)
    resp = requests.get(url, headers={"Authorization": "Bearer {}".format(token)})
    print (len(resp.json()))
    return resp.json()

def get_user_playlists(token, user_id):
    url = GET_USER_PLAYLISTS_ENDPOINT..format(id=user_id)
    resp = requests.get(url, headers={"Authorization": "Bearer {}".format(token)})
    print (len(resp.json()))
    return resp.json()

但为了首先获取(和更改)用户数据,我需要使用此令牌来获取 用户 ID


此外,通过以下示例形式的 Spotipy 文档,用户必须在终端提供他的 用户名

if __name__ == '__main__':
    if len(sys.argv) > 1:
        username = sys.argv[1]
    else:
        print("Whoops, need your username!")
        print("usage: python user_playlists.py [username]")
        sys.exit()

    token = util.prompt_for_user_token(username)

    if token:
        sp = spotipy.Spotify(auth=token)
        playlists = sp.user_playlists(username)

看了 Spotify 和 Spotify 的文档后,有些事情还是不清楚:

  1. 是否可以仅通过令牌获取此用户 ID?

  2. 应用程序用户必须通过浏览器中的表单提供他的 Spotify 用户名除了授权应用程序何时提示身份验证?

  3. 是否可以调整上面的包装器并实现一个考虑隐式流所需参数的客户端? spotify = spotipy.Spotify(auth=token) 可以工作并获取当前的用户数据吗?

Also, by the following example form Spotipy docs, user must provide his username at terminal:

那是因为 Spotipy 在磁盘上缓存令牌。当用户没有指定缓存路径时,用户名会简单地附加到文件的文件扩展名中,如 here 所示。因此,指定的用户名永远不会传输到任何 Spotify API 端点。

1) Is it possible to get this USER ID from passing the token only?

是的,使用 /v1/me 而不是 /v1/users/{user_id} 将完全做到这一点,假设您使用的是授权代码流或隐式授权流生成的访问令牌。

2) Must the app user necessarily provide his Spotify username via a form in a browser, besides authorizing the app when authentication is prompted?

没有,如我回答的第一段所示。

3) Is it possible to tweak the wrapper above and implement a client which contemplates the parameters required for implicit flow? Would simply spotify = spotipy.Spotify(auth=token) work and get current usr data?

Spotipy 现在似乎只使用授权代码流。因为你说你是

trying to implement a simple python client for Spotify api.

您应该只在您的应用程序中实施隐式授权流程。 This 包含所有三个 Spotify 授权流程的示例。