提问人:Stan 提问时间:11/8/2023 最后编辑:Stan 更新时间:11/10/2023 访问量:57
Google Script Request to App Store Connect 错误
Google Script Request to App Store Connect Error
问:
我在 Google Script 中编写了代码,当我运行它时出现错误:
{
"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"
}]
}
从脚本生成的令牌是用正确的标头形成的,但警告签名无效,我在这里检查了它 - https://jwt.io/ 签名编码时看起来像问题。
代码如下:
const createJwt = ({ privateKey, expiresInMins, data = {} }) => {
// Sign token using HMAC with SHA-256 algorithm
const header = {
alg: 'ES256',
kid: '**kid**',
typ: 'JWT'
};
const now = Date.now();
const expires = new Date(now);
expires.setMinutes(expires.getMinutes() + expiresInMins);
// iat = issued time, exp = expiration time
const payload = {
exp: Math.round(expires.getTime() / 1000),
iat: Math.round(now / 1000),
};
// add user payload
Object.keys(data).forEach(function (key) {
payload[key] = data[key];
});
const base64Encode = (text, json = true) => {
const data = json ? JSON.stringify(text) : text;
return Utilities.base64EncodeWebSafe(data).replace(/=+$/, '');
};
const toSign = `${base64Encode(header)}.${base64Encode(payload)}`;
const signatureBytes = Utilities.computeHmacSha256Signature(toSign, privateKey);
const signature = base64Encode(signatureBytes, false);
return `${toSign}.${signature}`;
};
const generateAccessToken = () => {
// Your super secret private key
const privateKey = '**private key**';
const accessToken = createJwt({
privateKey,
expiresInMins: 10,
data: {
iss: '**iss**',
aud: 'appstoreconnect-v1'
},
});
Logger.log(accessToken);
getUsers(accessToken);
};
function getUsers(accessToken){
url = 'https://api.appstoreconnect.apple.com/v1/users';
const optionsUsrGet = {
method: 'GET',
muteHttpExceptions: true,
contentType: "application/json",
headers: {
'Authorization': "Bearer " + accessToken}
};
const responseUsrGet = UrlFetchApp.fetch(url, optionsUsrGet);
if (responseUsrGet.getResponseCode() !=200 ) {
Logger.log(responseUsrGet);
service.reset();
fail;
};
const data = JSON.parse(responseUsrGet);
Logger.log(data);
}
更新:
通常,.p8 格式的密钥是从 App Store Connect 下载的,如下所示:
-----开始私钥----- MIGTAgEAMBMDByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgnUaBH3umCqbyl6w4 NBE9YxD42J2AFBXjfd8+tvVOQrOgCgYIKoZIzj1OPQehASVSAAS4fh1BhWSzj0PV vgIIllp9BQZKTNopsesddJ5ofmKYO/m7al9Pk1KAvN0vQRJKyHJ8A0sJUc0bljDSTm GWB4LPo -----结束私钥-----
在描述中,密钥应使用 ES256 算法 (ECDSASha256) 进行加密,判断为 事实证明,整个 Google 脚本只能 RsaSha256 或 HmacSha256 该行:const signatureBytes = Utilities.computeRsaSha256Signature(toSign, privatekey) 错误地对数据进行签名,这就是我无法通过 Apple API 连接的原因。
我拿了 RSA PKCS#8 测试密钥:
-----开始私有化钥匙----- MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqPfgaTEWEP3S9w0t gsicURfo+nLW09/0KfOPinhYZ4ouzU+3xC4pSlEp8Ut9FgL0AgqNslNaK34Kq+NZ jO9DAQIDAQABAkAgkuLEHLaqkWhLgNKagSajeobLS3rPT0Agm0f7k55FXVt743hw Ngkp98bMNrzy9AQ1mJGbQZGrpr4c8ZAx3aRNAiEAoxK/MgGeeLui385KJ7ZOYktj hLBNAB69fKwTZFsUNh0CIQEJQRpFCcydunv2bENcN/oBTRw39E8GNv2pIcNxZkcb NQIgbYSzn3Py6AasNj6nEtCfB+i1p3F35TK/87DlPSrmAgkCIQDJLhFoj1gbwRbH /bDRPrtlRUDDx44wHoEhSDRdy77eiQIgE6z/k6I+ChN1LLttwX0galITxmAYrOBh BVl433tgTTQ= -----结束私钥-----
在这种情况下,所有内容都已签名,但密钥不是来自 App Store Connect。
JWT 与来自 AppStore Connect 的密钥: eyJhbGciOiJFUzI1NiIsImtpZCI6Ik8xREszMUIyUkQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2OTk2MTA2MzEsImlhdCI6MTY5OTYxMDAzMSwiaXNzIjoiM2NvcDMyMTYtZD kyMS00YTU0LWEyZTUtN2o5MTc4Yjg5YWMzIiwiYXVkIjoiYXBwc3RvcmVjb25uZWN0LXYxIn0.F1wiu601YWLL3ZXPTu8f_m-ggTqeVavihye_ToesaJs
需要通过 API 从 App Store Connect 获取用户列表
答: 暂无答案
评论
The generated token from the script is formed with the correct headers
accessToken
About The generated token from the script is formed with the correct headers, can we consider that your accessToken is a valid value?