【iOS】App Store Connect APIとは?JWTの取得方法と使い方
この記事からわかること
- App Store Connect APIとは?
- JWT(JSON Web Token)とは?
- APIキーの取得方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- watchOS:10.1
- Swift:5.9
- macOS:Sonoma 14.1
公式リファレンス:App Store Connect API
App Store Connect APIとは?
「App Store Connect API」とはAppleが公式で提供しているApp Store Connectでの処理を自動化するためのREST APIです。このAPIを使用することでApp Store Connectで手動で行っていた以下の作業などをプログラムを介して実行することができるようになります。
- アプリケーションのメタデータ管理
- ビルドのアップロードやApp Storeへの提出
- TestFlight:テスターの管理、ベータ版アプリケーションの配布、フィードバックの収集
- アプリの売上、インストール数、ダウンロード数などのデータの取得
- チームメンバーの管理、権限の設定
- etc..
仕組みとしては認証した状態でエンドポイントに対して特定のJSON形式のデータを送信するだけです。
https://api.appstoreconnect.apple.com/v1/
認証にはJWT(JSON Web Token)という仕組みを用いています。
JWT(JSON Web Token)とは?
JWT(JSON Web Token)とはJSON形式の認証情報を符号化したトークンです。JWTは以下の3つの部分から構成されており、これらの値をBase64URL方式で符号化し、それをピリオド(.)で連結した値になります。
- ヘッダー (Header):トークンや署名の形式情報
- ペイロード (Payload):情報の本体
- 署名 (Signature):認証情報本体
App Store Connect APIでは暗号化アルゴリズムはES256
でないといけないようで、トークンの有効時間も20分以上に設定すると無効になってしまうようです。
JWTの生成方法
公式リファレンス:Creating API Keys for App Store Connect API
JWTを生成するにはApp Store ConnectからダウンロードしたAPIキーを使用します。このAPIキーは「Team(チーム)キー」と「Individual(個人)キー」の2種類があるようです。
APIキーを取得するにはApp Store Connectの「ユーザーとアクセス」>「統合」>「App Store Connect API」を開きます。ここからチームキーと個人キーを生成することができます。(私の場合は個人キーはローディングが終わらず生成できませんでした)
初めて生成する場合は「アクセス権をリクエスト」をクリックして承認してもらう必要があります。
これを押下するとポップアップが表示され、「提出」をクリックするとすぐに承認されました。
承認されると画面が変わりAPIキーが生成できるようになります。、「APIキーを生成」をクリックします。
キーの名称と権限を指定します。
これでAPIキーが生成されたのでダウンロードしていきます。(ダウンロードは1回しかできません)ダウンロードすると.p8
形式のファイルが取得できます。またここに表示されている「IssuerID」と「キーID」は後で使用するのでコピーしておいてください。
rubyスクリプトでトークンを生成
続いて取得したAPIキーを使用してJWTを実際に生成します。生成する方法はいろいろあるようですがひとまず動作確認をするためのRubyのスクリプトを実装します。
APIキーがあるディレクトリに合わせて「token.rb」ファイルを作成します。
$ touch token.rb
中に以下のように記述しISSUER_ID
とKEY_ID
、APIキーファイルのパスを自身のものに置き換えます。
参考文献:App Store Connect APIの叩き方
# Base64エンコーディングをサポートするライブラリを読み込む
require "base64"
# JSON Web Token (JWT) を生成および検証するためのライブラリを読み込む
require "jwt"
# App Store ConnectのISSUER IDを設定(自分のISSUER_IDに置き換える)
ISSUER_ID = "自分のISSUER_ID"
# App Store ConnectのキーIDを設定(自分のKEY_IDに置き換える)
KEY_ID = "自分のKEY_ID"
# 秘密鍵を読み込み、OpenSSLのPKeyオブジェクトとして格納
# 自身の秘密鍵のファイルパスに置き換える
private_key = OpenSSL::PKey.read(File.read("./作成したAPIキー.p8"))
# JWTトークンを生成する
token = JWT.encode(
{
# トークンの発行者(ISSUER ID)
iss: ISSUER_ID,
# トークンの有効期限(現在時刻から20分後)
exp: Time.now.to_i + 20 * 60,
# トークンの対象(audience)
aud: "appstoreconnect-v1"
},
# 秘密鍵
private_key,
# 署名アルゴリズム(ES256)
"ES256",
# トークンのヘッダーに追加するフィールド
header_fields={
# キーID
kid: KEY_ID
}
)
# 生成されたJWTトークンを出力する
puts token
完成したら以下コマンドを実行するとピリオド(.)で連結されたJWTを取得することができます。
$ ruby token.rb
取得したJWTを使用してAPIを叩いてみます。/apps
を指定することでApp Store Connect内のアプリ情報(アプリ名やバンドルID、レビューの数など)をJSON形式で取得することができます。
curl https://api.appstoreconnect.apple.com/v1/apps -H "Authorization: Bearer [取得したJWT]"
{
"data" : [ {
"type" : "apps",
"id" : "XXXXXXXXXXX",
"attributes" : {
"name" : "アプリ名1",
"bundleId" : "com.sample.XXXXXXXXX",
"sku" : "XXXXXXXXXXXXXXXXXXX",
"primaryLocale" : "ja",
"isOrEverWasMadeForKids" : false,
"subscriptionStatusUrl" : null,
"subscriptionStatusUrlVersion" : null,
"subscriptionStatusUrlForSandbox" : null,
"subscriptionStatusUrlVersionForSandbox" : null,
"contentRightsDeclaration" : "USES_THIRD_PARTY_CONTENT"
},
// 〜〜〜〜〜〜〜〜〜〜〜
}, {
"type" : "apps",
"id" : "XXXXXXXXXXX",
"attributes" : {
"name" : "アプリ名2",
"bundleId" : "com.sample.XXXXXXXXX",
"sku" : "XXXXXXXXXXXXXXXXXXX",
"primaryLocale" : "ja",
"isOrEverWasMadeForKids" : false,
"subscriptionStatusUrl" : null,
"subscriptionStatusUrlVersion" : null,
"subscriptionStatusUrlForSandbox" : null,
"subscriptionStatusUrlVersionForSandbox" : null,
"contentRightsDeclaration" : "USES_THIRD_PARTY_CONTENT"
},
}
}]
}
トークンの有効時間の20分を経過してリクエストを送信すると以下のように認証エラー(401)が返ってくるようになります。
{
"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"
}]
}
ご覧いただきありがとうございました。