sk

開発で得たこと

GitHubAppsでjwtとアクセストークンを取得する(Rails/Ruby)

前提

  • GitHub Appsを登録していること

JWTの取得

json web tokenを発行します。

foo.rb

private_pem = File.read('/Users/ユーザー名/.ssh/hoge.pem')
private_key = OpenSSL::PKey::RSA.new(private_pem)



# Generate the JWT
payload = {
  # issued at time
  iat: Time.now.to_i,
  # JWT expiration time (10 minute maximum)
  exp: Time.now.to_i + (10 * 60),
  # GitHub App's identifier
  iss: payloadナンバー
}

jwt = JWT.encode payload, private_key, "RS256"

p jwt

これでjwtを取得できます。 pemファイルはローカルであれば.ssh配下に置いてください。

以下のコマンドで.sshディレクトリに入ってダウンロードしたファイルを置けばOKです。

cd ~/.ssh

実行すると、以下のようにjson web tokenが返ってきます。

$ ruby foo.rb
"ながーい文字列"

アクセストークンの取得

先ほど取得したjwtを使用してアクセストークンを取得します。

ただここでinstallation_idというものが必要になるのですが、GitHubのリファレンスにその在りかが書いてません。

このidを取得するには Settings > Developer settings > GitHub Apps > GitHub Apps名 でappsの編集画面に行きます。 左のナビゲーションタブに「Advanced」というタブがあるのでそちらをクリックし、「Recent Deliveries」と書かれたログの中から installation で検索かけると発見できます。

Advanced f:id:sksksksksk:20180805203733p:plain

  "installation": {
    "id": xxxxxx
  }

jwtとinstallation_idを用いてpostしてあげると、 アクセストークンを取得できます。

uri = URI.parse "https://api.github.com/installations/installation_id/access_tokens"
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{jwt}"
request["Accept"] = "application/vnd.github.machine-man-preview+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

p json = JSON.load(response.body)
p json['token']

レポジトリの取得

おまけにレポジトリまで取得してしまいましょう。 基本的にはGitHubAPIと同じコードをかけばよいです。

uri = URI.parse("https://api.github.com/installation/repositories")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "token #{json['token']}"
request["Accept"] = "application/vnd.github.machine-man-preview+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

puts JSON.pretty_generate(JSON.load(response.body))

ここではrubyの標準ライブラリである net/http を使ってますが、もう少し本格的に実装する場合はHttpartyをオススメします。

参考

developer.github.com

ProgateやRailsチュートリアル、プログラミングスクールを通い終えたが現場のコードはかけない、

一体どうやって書くの?と思っているエンジニアのみなさんのためのチュートリアルを公開しています。

チュートリアル