bbd108
bbd108

Reputation: 998

Python JSON Web token (JWT) GET request 401 error with Apple Store Connect

In order to generate the token for API Requests, apple outlines the following steps.

The key, kid, and iss have all been verified to work. However in the following python script,

import jwt
import requests

# pseudo, removed secret info
# read the file, currently binary but have tried string too
with open('AuthKey_4..._.p8', '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': '6...', 
                    'exp': f'{expir}', 
                    'aud': 'appstoreconnect-v1'},
                    secret, algorithm='ES256', 
                    headers={'alg': 'ES256', 'kid': '4...', 'typ': 'JWT'})

# decode the bytes and create the get request header
s_token = token.decode('utf-8')
headers = {'Authorization': f'Bearer {s_token}'}

# send the get request
r = requests.get('https://api.appstoreconnect.apple.com/v1/salesReports',
                 headers=headers)#, params=params)

r.json() simply returns

{'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'}]}

In addition the link in the error message appears to be broken as well.

I have tried reading in the .p8 file in both binary and the regular string representation. I have tried passing different values in the token, removing certain values etc. I also have tried not passing the payload parameters into the GET request which also results in a 401 error. The payload information is listed here. Any help appreciated.

Upvotes: 4

Views: 2704

Answers (1)

bbd108
bbd108

Reputation: 998

exp cannot be a string...

import jwt
import requests
import time

# pseudo, removed secret info
# read the file, currently binary but have tried string too
with open('AuthKey_4..._.p8', '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': '6...', 
                    'exp': expir, 
                    'aud': 'appstoreconnect-v1'},
                    secret, algorithm='ES256', 
                    headers={'alg': 'ES256', 'kid': '4...', 'typ': 'JWT'})

# create the get request header
headers = {'Authorization': f'Bearer {token}'}

# send the get request
r = requests.get('https://api.appstoreconnect.apple.com/v1/salesReports',
                 headers=headers)#, params=params)

Upvotes: 7

Related Questions