I have the following implementation in JS/Node for interacting with App Store server, yet all responses are 401 Unauthorized
:
% curl -v -H 'Authorization: Bearer ***' "https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/4"
* Trying 17.56.138.10...
* TCP_NODELAY set
* Connected to api.storekit-sandbox.itunes.apple.com (17.56.138.10) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
* subject: businessCategory=Private Organization; jurisdictionCountryName=US; jurisdictionStateOrProvinceName=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; OU=management:idms.group.506364; CN=commercegateway.itunes.apple.com
* start date: Jun 4 18:57:38 2021 GMT
* expire date: Jul 4 18:57:37 2022 GMT
* subjectAltName: host "api.storekit-sandbox.itunes.apple.com" matched cert's "api.storekit-sandbox.itunes.apple.com"
* issuer: C=US; O=Apple Inc.; CN=Apple Public EV Server RSA CA 2 - G1
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fca1e00d600)
> GET /inApps/v1/subscriptions/4 HTTP/2
> Host: api.storekit-sandbox.itunes.apple.com
> User-Agent: curl/7.64.1
> Accept: */*
> Authorization: Bearer ***
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 1024)!
< HTTP/2 401
< server: daiquiri/3.0.0
< date: Thu, 26 Aug 2021 02:57:57 GMT
< content-type: text/plain
< strict-transport-security: max-age=31536000; includeSubDomains
< x-apple-jingle-correlation-key: KPN55ROQH3BLNL2AG7S7NEFZHA
< x-daiquiri-instance: daiquiri:17578001:mr85p00it-hyhk04164801:7987:21RELEASE140:daiquiri-amp-commerce-clients-ext-002-mr
<
Unauthenticated
Request ID: KPN55ROQH3BLNL2AG7S7NEFZHA.0.0
* Connection #0 to host api.storekit-sandbox.itunes.apple.com left intact
* Closing connection 0
The header is hashed with ES256 as follows:
function jwtHeader() {
let d = new Date()
d.setHours(d.getHours() + 1)
return {
"iss": issuerID,
"iat": Math.floor(new Date().getTime()/1000),
"exp": Math.floor(d.getTime()/1000),
"aud": "appstoreconnect-v1",
"nonce": Utils.uuid(),
"bid": bundleID
}
}
function headerHash(cb) {
fs.readFile(appleKeys.p8, 'utf-8', function(err, key) {
if (err) return cb(err)
let headers = jwtHeader()
console.log(headers)
jwt.sign(headers, key, { algorithm: 'ES256' }, cb)
})
}
My In-App Purchase Key ID is completely unused. Besides registering a callback for notifications, I can't find anywhere to register my URL. In short, I can't tell what's not configured or carried out improperly on my end.
Can you please ensure you are providing the correct information in the Header it should contain alg, kid, type. Below is an example payload for the header.
{ "alg": "ES256", "kid": "2X9R4HXF34", "typ": "JWT" }
Please refer to the links below for more information:
Creating API Keys to use with the App Store API: https://developer.apple.com/documentation/appstoreserverapi/creating_api_keys_to_use_with_the_app_store_server_api
Generating Tokens for API requests: https://developer.apple.com/documentation/appstoreserverapi/generating_tokens_for_api_requests