【问题标题】:Generating token for App Store Connect API为 App Store Connect API 生成令牌
【发布时间】:2019-06-14 16:30:42
【问题描述】:

我需要为Store Connect API 生成 JWT 令牌。我正在尝试使用 jwt ruby​​ gem ruby-jwt。这是我的令牌生成代码,

payload = {
      'iss': my_issuer_id_from_db,
      'exp': generated_unix_timestamp, #Time.now + 20min
      'aud': 'hard_coded_string_from_doc'
  }
  header = {
      'alg': 'ES256',
      'kid': my_key_id_from_db,
      'typ': 'JWT'
  }

private_key = OpenSSL::PKey.read(File.read('/tmp/private_key.pem'))
# private_key - <OpenSSL::PKey::EC:0x000000000XXXXXXX>

@token = JWT.encode(payload, private_key, 'ES256', header)
# encoded_header.encoded_payload.emcoded_signature

我将这个令牌放入请求的标头中:

headers = { Authorization: 'Bearer' + @token }

在我收到的回复中:

        "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"
        }]
}

我认为问题在于令牌(直接带有签名)。当我尝试使用online tool 解码令牌时,我的有效负载和标头已正确解码。状态:无效签名

我做错了什么?任何想法如何正确地做到这一点?

【问题讨论】:

  • 1.在“Bearer”和令牌之间放置一个空格。标题应该是'Authorization: Bearer eyJ...' 2. 在 jwt.io 上,您是否将密钥粘贴到密钥字段中?许多人忘记了这一点,并想知道为什么该工具会显示“无效签名”
  • 我试过了,但是 jwt.io 工具需要公钥和私钥。我只有私钥。
  • 第一点是原因。
  • 嘿,我也面临同样的问题。你是如何解决这个问题的?你能很好地分享整个 ruby​​ 文件吗?谢谢!

标签: ruby jwt app-store-connect itunes


【解决方案1】:

我遇到了类似的身份验证错误,即 NOT_AUTHORIZED。我通过以下步骤解决了它:

1。创建 Ruby Script 文件以生成有效的Bearer Token:

参考: https://medium.com/xcblog/generating-jwt-tokens-for-app-store-connect-api-2b2693812a35

require "base64"
require "jwt"
ISSUER_ID = "YOUR_ISSUER_ID"
KEY_ID = "YOUR PRIVATE KEY ID"    // this is ID part from downloaded .p8 file name (see below for ref.)
private_key = OpenSSL::PKey.read(File.read(path_to_your_private_key/AuthKey_#{KEY_ID}.p8))   // you can enclose your file path in quotes if needed, and can pass here totally static file path (here we are reusing Key_ID variable)

token = JWT.encode(
   {
    iss: ISSUER_ID,
    exp: Time.now.to_i + 20 * 60,
    aud: "appstoreconnect-v1"
   },
   private_key,
   "ES256",
   header_fields={
       kid: KEY_ID }
)
puts token

然后在您的 Mac 上使用以下命令运行此脚本。

$ ruby jwt.rb

这将在您的终端屏幕上显示一个有效的Bearer 令牌,您可以在下一步中使用它。

注意事项:

  • 要运行上述脚本,您需要安装 ruby
  • 您将从您的开发者帐户中复制颁发者 ID。如果没有,请生成一个。
  • 确保您对经过身份验证的用户使用“.p8”证书,这意味着您下载“.p8”证书的帐户应该有权执行 API 级别的操作。对于我的情况,我使用了 Admin 类型的帐户。最初我使用的是 Developer 类型的用户帐户,当我进行最终的 Curl 调用以获取令牌时,它一直给我 Not_Authorized 错误。

2。使用令牌:

现在,我们已经了解了如何生成令牌来访问 App Store Connect API,我们可以通过传递授权标头来使用它。例如,获取我们可以使用的所有用户的列表

$ curl  https://api.appstoreconnect.apple.com/v1/users --Header "Authorization: Bearer lOOOOOOOOOOOONG_GENERATED_TOKEN"

这将列出 App Store Connect 的所有用户。请记住,我们必须在我们提出的每个请求中使用此令牌,并且我们必须在每 20 分钟后创建新令牌。

【讨论】:

  • 这个从 xcblog medium.com/xcblog/… 粘贴的示例副本即使在删除 cmets 并填写合法值后也不起作用。它可能与不使用 header_fields 的方式有关。 (在文件上尝试 rubocop。)
  • 确保已安装 JWT gem 以使脚本正常工作sudo gem install jwt
【解决方案2】:

您传入的授权字符串中缺少空格。修改为后您的代码工作正常

headers = { Authorization: 'Bearer ' + @token }

【讨论】:

    【解决方案3】:

    我刚刚在这里创建了 python3 版本。 401 Authentication credentials are missing or invalid 可能与获取时间有关issuedexpired

    检查你的函数获取时间是苹果推荐的UNIX epoch time

    import jwt
    import datetime as dt
    
    key_id = '#####' 
    alg = 'ES256'
    typ = 'JWT'
    issue_id = '##########################'
    aud = 'appstoreconnect-v1'
    
    # Define issue timestamp.
    issued_at_timestamp = int(dt.datetime.now().timestamp())
    # Define expiration timestamp. May not exceed 20 minutes from issue timestamp.
    expiration_timestamp = issued_at_timestamp + 20*60
    
    # Define JWT headers.
    headers = dict()
    headers['alg'] = alg
    headers['kid'] = key_id
    headers['typ'] = typ
    
    # Define JWT payload.
    payload = dict()
    payload['iss'] = issue_id
    payload['iat'] = issued_at_timestamp
    payload['exp'] = expiration_timestamp
    payload['aud'] = aud
    
    # Path to signed private key.
    KEY_FILE = '#########.p8' 
    
    with open(KEY_FILE,'r') as key_file:
         key = ''.join(key_file.readlines())
    
    client_secret = jwt.encode(
    payload=payload,  
    headers=headers,
    algorithm=alg,  
    key=key
    )
    
    with open('client_secret.txt', 'w') as output: 
         output.write(client_secret)
        
        
    # Usage, after run this code by python3
    # get token from `client_secret.txt` and replace to [signed token]
    # Remember expired time maximum is 20 minutes
    #
    # curl -v -H 'Authorization: Bearer [signed token]' "https://api.appstoreconnect.apple.com/v1/apps"
    #
    # More detail https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-11
      • 2019-06-24
      • 2020-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 2021-03-18
      相关资源
      最近更新 更多