This is my code:
import jwt from 'jsonwebtoken'
import path from 'path'
import fs from 'fs'
// You get privateKey, apiKeyId and issuerId from your Apple App Store Connect account
const filePath = path.resolve(
__dirname,
<PATH_TO_PRIVATE_KEY>
)
const privateKey = fs.readFileSync(filePath)
// this is the file you can only download once and should treat like a real, very precious key.
const apiKeyId = <API_KEY_ID>
const issuerId = <ISSUER_ID>
let payload = {
"iss": issuerId,
"aud": "appstoreconnect-v1"
}
let token = jwt.sign(payload, privateKey, {
algorithm: 'ES256',
expiresIn: '60m',
header: {
alg: 'ES256',
kid: apiKeyId,
typ: 'JWT',
}
});
console.log('@token: ', token);
// Congrats! the token printed can now be tested with the curl command below
// curl -v https://api.appstoreconnect.apple.com/v1/apps --Header "Authorization: Bearer <YOUR TOKEN>"
I ran this script to test the token and call the GET curl like this, but still got 401 unauthorized.
curl -v https://api.appstoreconnect.apple.com/v1/apps --Header "Authorization: Bearer <token>"
This is the the error text:
text: '{\n' +
'\t"errors": [{\n' +
'\t\t"status": "401",\n' +
'\t\t"code": "NOT_AUTHORIZED",\n' +
'\t\t"title": "Authentication credentials are missing or invalid.",\n' +
'\t\t"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"\n' +
'\t}]\n' +
'}',
I used jwt.io to verify that the token has valid expiration date.
The decoded token from jwt.io gives me these info:
payload:
{
"iss": <ISSUER_ID>,
"iat": 1696812284,
"exp": 1696815884, // an hour from the issued at time
"aud": "appstoreconnect-v1"
}
header:
{
"alg": "ES256",
"typ": "JWT",
"kid": <API_KEY_ID>
}
I am not so sure what can cause this 401 Unauthorized error.