PythonからDriveAPIをサービスアカウントでブラウザ認証せずに利用する

PythonからDriveAPIをサービスアカウントでブラウザ認証せずに利用する

Google DriveAPIを利用するための認証方法としてOAuth2.0を利用してきたけどwebサーバー上でどのように認証したら良いのかわからない、ブラウザでの認証がめんどくさいと思ったことがある人はいると思います。

そのような方のためにこの記事では、サービスアカウントを利用してDriveAPIを利用する方法を紹介します。

サービスアカウントを利用することでOAuth2.0はいらなくなるので、ブラウザでの認証が不必要になりますし、webサーバでも利用することが可能になります。

こちらのGoogle Cloudのブログが参考にしています。下記の手順で説明していきます。

  1. サービスアカウントの作成
  2. Google Driveの共有設定
  3. Pythonプログラムの作成

FlaskなどでWebアプリケーションを構築するときにOAuth2.0のブラウザ認証などは利用したくありませんよね!

ちなみに、下記の記事ではユーザアカウントとOAuth2.0を利用して、PythonからDriveAPIを経由でGoogle Driveに接続する方法を紹介しています。

サービスアカウントについて

今回利用するサービスアカウントについて軽く説明します。

サービスアカウントとは、人間以外のユーザのことです。Googleのサービスを使用するときに使っている一般的なアカウント(<user account>@gmail.comなど)は人間と紐付いていますが、サービスアカウントはサービスと結びつきます。

サービスアカウントと一般的なユーザアカウントの主な違いは下記の3つになります。

  • サービスアカウントはパスワードを持たないので、ブラウザベースのログインはできない
  • サービスアカウントはGoogleCloudプロジェクトのリソースとして作成される(一方で、ユーザアカウントはGoogle Workspaceなどで管理される)
  • サービスアカウントはGoogleCloudでのみ利用できる

つまり、サービスアカウントはGoogleCloud内で利用できるサービスのためのアカウトということです。

個人的に重要だと思うポイントは、サービスアカウントもGoogleCloud内で擬似的なメールアドレスを持つということです!

プロジェクトの作成とDriveAPIの有効化

それでは本題に入っていきます。

まず、GCPでプロジェクトの作成とDriveAPIの有効化を行います。これらは前回の記事にまとめているので、そちらを参考に進めてください。

プロジェクトの作成:https://takake-blog.com/python-driveapi/#Google_Cloud_PlatformGCP

DriveAPIの有効化:https://takake-blog.com/python-driveapi/#Drive_API

サービスアカウントの作成

次にGoogleDriveに接続するサービスアカウントを作成していきます。

1.
GCPへアクセスして、「IAMと管理」に移動して、左タブからサービスアカウントを選択します。
画面上部に「+サービスアカウントを作成」ボタンがあるのでクリックします。

2.
サービスアカウント名とサービスアカウントの説明を入力したら、完了ボタンをクリックします。
DriveAPIにはロール権限などは必要ないので、、「このサービスアカウントにプロジェクトへのアクセスを許可する」と「ユーザーにこのサービスアカウントへのアクセスを許可」は無視で良いです。

3.
作成したサービスアカウントの鍵を取得しましょう。サービスアカウントを作成したらサービスアカウント一覧画面に推移するので、左側の操作ボタンから「鍵を管理」をクリックしてください。

4.
鍵の管理画面に推移したら、「鍵を追加」ボタンをクリックして、「新しい鍵を作成」ボタンをクリックしてください。ファイルの形式を聞かれるので、JSONで作成してください。

鍵を作成したら、自動的に作成した鍵情報のjsonファイルがダウンロードされます。

Google Driveの共有設定

サービスアカウントがGoogleDrive内のフォルダに接続するためには、フォルダに対して共有設定を行う必要があります。

サービスアカウントを作成したときに発行されるメールアドレスを利用して、フォルダの共有設定を行っていきます。

  1. ブラウザからGoogle Driveに移動します
  2. DriveAPI経由でアクセスしたフォルダ( or ファイル)を右クリックします
  3. 「共有」ボタンをクリックします
  4. ユーザやグループの追加画面に推移するので、先程作成したサービスアカウントのメールアドレスをコピーします
  5. 適切な権限(ここでは編集者)を選択して、サービスアカウントを追加します。

これで、サービスアカウントがGoogle Driveに接続可能になりました。

Pythonプログラムの作成

最後に、DriveAPIを利用してGoogleDriveに接続するPythonプログラムを作成します。鍵を作成したときに取得したjsonファイルを利用します。

GoogleDriveにある共有フォルダ内のファイル一覧を取得するサンプルプログラムです。

フォルダIDは、GoogleDriveのURLの最後の部分です。(https://drive.google.com/drive/folders/<folder id>

サービスアカウントの認証情報は、credentials.jsonという名前に変更してあります。

from googleapiclient.discovery import build
from google.oauth2 import service_account
from googleapiclient.errors import HttpError as HTTPError
SCOPES = ['https://www.googleapis.com/auth/drive']
SHARE_FOLDER_ID = 'your folder id'
sa_creds = service_account.Credentials.from_service_account_file( 'credentials.json')
scoped_creds = sa_creds.with_scopes(SCOPES)
drive_service = build('drive', 'v3', credentials=scoped_creds)
response = drive_service.files().list( supportsAllDrives=True, includeItemsFromAllDrives=True, q=f"parents in '{SHARE_FOLDER_ID}' and trashed = false", fields="nextPageToken, files(id, name)").execute()
for file in response.get('files', []): print(f"Found file: {file.get('name')} ({file.get('id')})")

上記を実行して、ファイル名とファイルIDが出力されていれば成功です。

まとめ

webサーバーからGoogleDriveに接続したい!OAuthの認証がめんどくさい!という方を対象に、サービスアカウントを利用してGoogleDriveに接続する方法を紹介しました。

GoogleDriveで共有設定をする必要はありますが、Webアプリケーションを開発していく上で、開発が簡単になる予感です。

Googleのサービスは本当に便利ですね!