LoginSignup
2
3

More than 5 years have passed since last update.

GCPのアクセストークンを取得する

Posted at

環境

  • ruby歴 初心者
  • rails 5.0.2
  • ruby 2.4.1p111

これはなに?

GCPのアクセストークンを取得するAPIを実装しました。

最終的には、クライアントがこのアクセストークンを用いて
GCSにあるプライベートなファイルを操作するために使用します。

発端

iOSでGCSにあるプライベートなファイルを操作する際に下記の問題点ありました。

  • aws-ios-sdk などのsdkが見当たらない
  • iOSで実装すると実装コストがかなり高くなる

そのためサーバーサイドでアクセストークンを発行し取得するAPIを
提供することになりました。

準備

アクセストークンを発行するには下記のものを用意する必要がありますので
GCPから取得しておいてください。

  • サービスアカウントID
  • サービスアカウントの証明書(p12ファイル)
  • 証明書のパスフレーズ

取得の流れはざっと下記のとおりです。

  1. GCPでプロジェクト作成
  2. サービスアカウント作成(ここでIDが手に入る)
  3. p12ファイルを生成

詳しくはこちらの記事をご参照ください。
※記事中ではjsonファイルを選択していますが、p12ファイルを選択してください。

サービスアカウントに持たせる権限は重要なので、どういった権限をもたせるかは
各自適した物を付与してください。
また実装時にも必要になるので覚えておいてください。

また、取得したp12ファイルのパスフレーズはデフォルトでnotasecretになっています。
これではセキュリティがガバガバなので、自前で変更しましょう。
変更方法の詳細はこちら

パスフレーズの変更が終わったら、必要なものをそれぞれ所定の場所に置きます。

  • サービスアカウントID
    → リポジトリに残さないため環境変数へ追加

  • サービスアカウントの証明書(p12ファイル)
    → プロジェクト内のフォルダに追加(credentialフォルダを作成しその配下に置いています。)

  • 証明書のパスフレーズ
    → リポジトリに残さないため環境変数へ追加

実装

準備ができたら実装に移ります。
まずは gem の導入です。
必要になるのはgoogle-api-clientです

Gemfile

gem 'google-api-client'

実装の本体は下記のような感じです。

storage.rb
require 'google/api_client/auth/key_utils'
require 'signet/oauth_2/client'

class Storage
  include ActiveModel::Model

  def initialize
    secret_key = Google::APIClient::KeyUtils.load_from_pkcs12(Rails.root.join('credential', 'keyfile.p12'), ENV.fetch('P12_PASSPHRASE'))
    @authorization = Signet::OAuth2::Client.new\
      token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
      audience: 'https://accounts.google.com/o/oauth2/token',
      scope: 'https://www.googleapis.com/auth/devstorage.read_write',
      issuer: ENV.fetch('GOOGLE_SERVICE_ACOUNT_ID'),
      signing_key: secret_key
  end

  def fetch_access_token
    @authorization.fetch_access_token!
  end
end

準備したものをそれぞれ使用し、認証ロジックを通してアクセストークンを生成します。
1つ気をつけるのが権限の範囲であるscopeです。

storage.rb
scope: 'https://www.googleapis.com/auth/devstorage.read_write'

このアクセストークンに持たせる権限になるのですが、サービスアカウントで付与した権限になります。
どの文字列になるかは、こちらを参照して適したものを記載してください。

以上で、実装は終わりです。
あとは、APIで返してあげるだけでOK

console
Storage.new.fetch_access_token

=>
{
    "access_token":"XXXXXXXXXX",
    "expires_in":3600,
    "token_type":"Bearer"
}

感想

今回は、p12ファイルでアクセストークンを取得しましたが
もし、jsonファイルでのアクセストークンの取得方法を知っておられる方は、ぜひとも教えていただきたいです:anguished:
パスフレーズを環境変数に逃しているとはいえ、p12ファイルをリポジトリに乗せるのは正直どうかと思いますので、、、、、
デプロイ時に rake task で含めるようにしろとか、それだと開発時めんどいだろとか
そういうのも含めてコメント頂けると幸いです:anguished:

参考リンク

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3