PythonでGCPの認証を行う
GCPの認証ってたまにどうやるんだっけ?って忘れてしまうので備忘録として残しておこうと思います。 今回はCloud Pub/Subを例に認証を行います。
今回使用する言語
- Python 3.7
予備知識
サービスアカウントとユーザーアカウントの認証の仕組みに関しては下記の記事が参考になります。
Cloud Pub/Subのlibraryの使い方に関しては下記になります。
サービスアカウントを用いて認証
環境変数を用いる
export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
上記のようにサービスアカウントが含まれるパスを指定してあげるとclient libraryが使えるようになります こちらの方法だとCloud Pub/SubにPublishする際は下記のように扱うことができます。
from google.cloud import pubsub_v1 import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") publisher = pubsub_v1.PublisherClient() topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
ファイルパスを指定して認証
google.oauth2.service_account moduleを使って認証するやり方です。SERVICE_ACCOUNT_FILE_PATH
の環境変数にファイルのパスを指定している感じです。
from google.cloud import pubsub_v1 from google.oauth2 import service_account import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") service_account_file_path = os.getenv("SERVICE_ACCOUNT_FILE_PATH", "") credentials = service_account.Credentials.from_service_account_file(service_account_file_path) publisher = pubsub_v1.PublisherClient(credentials=credentials) topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
データを直接読み込んで認証
同じように先ほどのgoogle.oauth2.service_account moduleを使います。
Credentialsクラスで定義されているfrom_service_account_infoメソッドを使うことでファイルパスを指定することなくサービスアカウントの情報を直接渡して認証できます。
特にコンテナなど、jsonファイルを中に置きたくない場合に有効なのかなと思います。SERVICE_ACCOUNT_FILE
の環境変数にサービスアカウントの情報が入ってます。
from google.cloud import pubsub_v1 from google.oauth2 import service_account import json import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") service_account_file = os.getenv("SERVICE_ACCOUNT_FILE", "") credentials = service_account.Credentials.from_service_account_info(json.loads(service_account_file)) publisher = pubsub_v1.PublisherClient(credentials=credentials) topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
JWTを使って認証
google.auth.jwt.Credentialsを使って認証する方法です。
先ほどのgoogle.oauth2.service_account moduleの認証でもJWTを内部で扱っているのですが、アクセストークンの扱い方がそれぞれ違うみたいです。簡単にまとめると
使用ライブラリ | 認証方法 |
---|---|
google.oauth2.service_account module | JWTを用いてoauth2.0のアクセストークンを獲得して、GCPの認証はoauth2.0のアクセストークンをBearerトークンとして行う |
google.auth.jwt.Credentials | JWTで生成したBearerトークンを使ってGCPの認証を行う |
のような違いがあるみたいです。
from google.cloud import pubsub_v1 from google.auth import jwt import json import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") service_account_file = os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "") publisher_audience = "https://pubsub.googleapis.com/google.pubsub.v1.Publisher" credentials = jwt.Credentials.from_service_account_info(json.loads(service_account_file), audience=publisher_audience) publisher = pubsub_v1.PublisherClient(credentials=credentials) topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
ユーザーアカウントを用いて認証
環境変数を用いて認証
サービスアカウントを用いた方法と変わらないです。GOOGLE_APPLICATION_CREDENTIALS
に使いたいユーザーアカウントのファイルパスを指定します。
ファイルパスを指定して認証
google.oauth2.credentials moduleを使って認証します。
from google.cloud import pubsub_v1 from google.oauth2 import credentials import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") user_account_path = os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "") credentials = credentials.Credentials.from_authorized_user_file(user_account_path) publisher = pubsub_v1.PublisherClient(credentials=credentials) topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
データを直接読み込んで認証
こちらも同じようにgoogle.oauth2.credentials moduleを使います。
from google.cloud import pubsub_v1 from google.oauth2 import credentials import json import os project_id = os.getenv("PROJECT_ID", "") topic_id = os.getenv("TOPIC_ID", "") user_account_file = os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "") credentials = credentials.Credentials.from_authorized_user_info(json.loads(user_account_file)) publisher = pubsub_v1.PublisherClient(credentials=credentials) topic_path = publisher.topic_path(project_id, topic_id) publisher.publish(topic_path, b"Hello World")
まとめ
google-authを眺めていると、まだ挙げていない認証方法もあるのかなと思います。最近は色々なクラウド環境を使う機会が増えてきたので、どのような認証方法が提供されているのか把握できてるとスムーズに開発が行えると思います。
とりあえずGCPの認証に関してはある程度理解できたので今後困ることはなさそうです。