尝试拨打Apple Music API时,我一直遇到401错误。我使用的是Windows机器,下面是它的Python代码。
import datetime
import jwt
secret = """-----BEGIN PRIVATE KEY-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
-----END PRIVATE KEY-----"""
kid = 'ABCDEFGHI'
teamId = 'JKLMNOPQRS'
alg = 'ES256'
headers = {
'alg': alg,
'kid': kid
}
payload = {
'iss': teamId,
'iat': 1518033023,
'exp': 1518290267
}
if __name__ == '__main__':
'''Create an auth token'''
token = jwt.encode(payload, secret, algorithm=alg, headers=headers)
print '----CURL----'
print ("curl -v -H 'Authorization: Bearer %s' \"https://api.music.apple.com/v1/catalog/us/playlists/pl.14362d3dfe4b41f7878939782647e0ba\" " % (token))
答案 0 :(得分:1)
我对字符串格式化操作符有同样的问题。因此请使用:
"""Create an auth token"""
token = jwt.encode(payload, secret, algorithm=alg, headers=headers)
token_str = token.decode('utf-8') # converts bytes to string
url = "https://api.music.apple.com/v1/catalog/us/playlists/pl.14362d3dfe4b41f7878939782647e0ba"
print("curl -v -H 'Authorization: Bearer" + token_str + "\"" + url + "\"")
此外:我假设您想直接访问数据。为此,您可以使用requests库:
import requests
request_obj = requests.get(url, headers={'Authorization': "Bearer " + token_str})
json_dict = request_obj.json()
干杯!
答案 1 :(得分:0)
添加到sanwall的答案–这对我有效(Python 3.x):
from datetime import datetime
import jwt
import requests
import json
secret_key = '''-----BEGIN PRIVATE KEY-----
... your secret key here ...
-----END PRIVATE KEY-----'''
key_id = '0123456789' # <-- your key id here
team_id = '0123456789' # <-- your team id here
alg = 'ES256'
iat = int(datetime.utcnow().strftime("%s")) # set issued at to now
exp = iat + 86400 # add e.g. 24h from now for expiration (24 * 3600secs == 86400)
payload = {
'iss': team_id,
'iat': iat,
'exp': exp
}
headers = {
'alg': alg,
'kid': key_id
}
token = jwt.encode(payload, secret_key, algorithm=alg, headers=headers)
token_str = token.decode('utf-8')
url = "https://api.music.apple.com/v1/catalog/us/songs/203709340"
print (f"curl -v -H 'Authorization: Bearer {token_str}' {url}")
或将请求与生成的令牌字符串一起使用:
res = requests.get(url, headers={'Authorization': "Bearer " + token_str})
result = json.loads(res.text)
打印输出:
{'data': [{'id': '203709340', 'type': 'songs', 'href': '/v1/catalog/us/songs/203709340', ... etc ...
答案 2 :(得分:0)
我遇到了同样的问题,对我来说,.p8文件应该只在其中一个文件上,所以它在多行上具有密钥:
-----BEGIN PRIVATE KEY-----
notarealkey5GSM49AgEGCCqGSM49AwEHBHkwdwIBAQQguWRXMHYkuFImkMGByqEPT
jaXQyO0WK1BjYpuDxIgNQ5nHRRFCuUOi8mgCgYIKoZIzj0DAQehcp0+Z+jwRANCAA
RCBFg8fL08QS36Fb8HmY+eFrDWMO00w5unCo5n8VyLhvttIZeByXlVsJrK/L3f/
F2wYmZme
-----END PRIVATE KEY-----
vs:
-----BEGIN PRIVATE KEY-----
asdfg1rty5GSM49AgEGCCqGSM49AwEHBHkwdwI...
-----END PRIVATE KEY-----
答案 3 :(得分:0)
Apple Music API需要开发者令牌和用户令牌。尽管问题是关于python的,但这个答案是为那些将来会遇到此问题的迅速开发人员准备的。
例如,
static func addPlaylistPathURLString(developerToken: String, userToken: String) -> URLRequest {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "api.music.apple.com"
urlComponents.path = "/v1/me/library/playlists/
// Create and configure the `URLRequest`.
var urlRequest = URLRequest(url: urlComponents.url!)
urlRequest.httpMethod = "GET"
urlRequest.addValue("Bearer \(developerToken)", forHTTPHeaderField: "Authorization")
urlRequest.addValue(userToken, forHTTPHeaderField: "Music-User-Token")
return urlRequest
}
func addPlaylistPathURLString(with developertoken: String, userToken: String, completion: @escaping CatalogSearchCompletionHandler) {
guard let developerToken = refreshDeveloperToken() // its developer token
else {
fatalError("Developer Token not configured. See README for more details.")
}
let urlRequest = AppleMusicRequestFactory.addPlaylistPathURLString(developerToken: developerToken, userToken: userToken)
print(urlRequest)
let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in
guard error == nil, let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 else {
completion([], error)
return
}
guard
let data = data,
let json = String(data: data, encoding: .utf8)
else { return }
print("json:", json)
do {
// do your stuffs---
} catch {
print("An error occurred: \(error.localizedDescription)")
}
}
task.resume()
}
关于如何从开发人员令牌中获取用户令牌,
func requestUserToken() {
guard let developerToken = appleMusicManager.refreshDeveloperToken() // its developer token
else {
return
}
if SKCloudServiceController.authorizationStatus() == .authorized {
let completionHandler: (String?, Error?) -> Void = { [weak self] (token, error) in
guard error == nil else {
print("An error occurred when requesting user token: \(error!.localizedDescription)")
return
}
guard let token = token else {
print("Unexpected value from SKCloudServiceController for user token.")
return
}
self?.userToken = token
print(token)
/// Store the Music User Token for future use in your application.
let userDefaults = UserDefaults.standard
userDefaults.set(token, forKey: AuthorizationManager.userTokenUserDefaultsKey)
userDefaults.synchronize()
if self?.cloudServiceStorefrontCountryCode == "" {
self?.requestStorefrontCountryCode()
}
NotificationCenter.default.post(name: AuthorizationManager.cloudServiceDidUpdateNotification, object: nil)
}
if #available(iOS 11.0, *) {
cloudServiceController.requestUserToken(forDeveloperToken: developerToken, completionHandler: completionHandler)
} else {
cloudServiceController.requestPersonalizationToken(forClientToken: developerToken, withCompletionHandler: completionHandler)
}
}
}