身份验证凭据丢失或应用商店连接api python无效



我正在尝试使用带有Python脚本的App Store Connect API中的销售报告API。

import jwt
import requests
import time
import json
KEY_ID = "XXXXXXXXX"
ISSUER_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# EXPIRATION_TIME = int(round(time.time() + (20.0 * 60.0))) # 20 minutes timestamp
PATH_TO_KEY = '/Users/164187.victor/Documents/Credentials/App_Store_Connect_RR/AuthKey_XXXXXXXXX.p8'
# pseudo, removed secret info
# read the file, currently binary but have tried string too
with open(PATH_TO_KEY, 'r+b') as keyfile:
secret = keyfile.read()
expir = round(time.time() + 20 * 60)
# sign the token with the iss, time, key, and kid with the correct alg
token = jwt.encode({'iss': ISSUER_ID, 
'exp': expir, 
'aud': 'appstoreconnect-v1'},
secret, algorithm='ES256', 
headers={'alg': 'ES256', 'kid': KEY_ID, 'typ': 'JWT'})
# decode the bytes and create the get request header
headers = {'Authorization': f'Bearer {token}'}
params = {'filter[reportSubType]': 'SUMMARY', 'filter[reportType]': 'SALES', 'filter[frequency]':'DAILY', 'filter[vendorNumber]': 'XXXXXXXX'}
# send the get request
r = requests.get('https://api.appstoreconnect.apple.com/v1/salesReports',
headers=headers, params=params)
# Write the response in a pretty printed JSON file
with open('output.json', 'w') as out:
out.write(json.dumps(r.json(), indent=4))

我在json输出文件中得到了这个结果:

{
"errors": [
{
"status": "401",
"code": "NOT_AUTHORIZED",
"title": "Authentication credentials are missing or invalid.",
"detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired. Learn more about Generating Tokens for API Requests https://developer.apple.com/go/?id=api-generating-tokens"
}
]
}

我尝试过的:

  1. 在jwt.io中检查我的令牌,它在那里确实很好
  2. 对密钥权限使用管理员访问级别
  3. 试图删除标头中的"alg"属性导致一些帖子说这会解决问题,但对我不起作用

有什么办法可以解决这个问题吗?我已经坚持了一个星期了,请帮助

给定错误中的链接,https://developer.apple.com/go/?id=api-生成令牌时,负载中缺少iat(Issued at Time(和scope参数。

您的代码似乎源于这个Gist,它使用authlib创建JWT令牌。但是代码中的import jwt语句表明您已经切换到PyJWT,不要混淆两个包,它们有不同的使用方式。

对于PyJWT:

import jwt
token_data = jwt.encode(
{
'iss': ISSUER_ID,
'aud': 'appstoreconnect-v1',
'exp': expiry
},
secret,
headers={
'kid': KEY_ID
},
algorithm='ES256'
)
print(token_data.decode('UTF-8'))

对于authlib:

from authlib.jose import jwt
token_data = jwt.encode(
{
"alg": "ES256",
"kid": KEY_ID,
"typ": "JWT"
},
{
"iss": ISSUER_ID,
"exp": expir,
"aud": "appstoreconnect-v1"
},
secret
)
print(token.decode())

对于这两种方式,在用于请求头之前,不要忘记调用decode()

另一个更好的选择是使用鼓掌——一个用于访问App Store Connect API的Python客户端库,您只需传递凭据即可初始化Connection对象,applaud为您完成其余操作:

# Create the Connection
connection = Connection(ISSUER_ID, KEY_ID, PRIVATE_KEY)
r = connection.sales_reports().filter(
report_sub_type=SalesReportsEndpoint.ReportSubType.SUMMARY, # or "SUMMARY"
report_type=SalesReportsEndpoint.ReportType.SALES, # or "SALES"
frequency=SalesReportsEndpoint.Frequency.MONTHLY, # or "MONTHLY"
report_date='2021-12',
vendor_number='12345678',
).get()
r.save('output.txt', decompress=True)

您可以在"付款"one_answers"财务报告"中找到您的供应商编号。示例代码在这里。

完全披露,我是原作者鼓掌。

最新更新