タグ: GCP

  • Google Cloud API認証の実装方法:YouTubeアップロードAPIを例に

    はじめに

    Google Cloud Platform(GCP)のAPIを利用する際、適切な認証が必要となります。特にOAuth 2.0認証フローを使用する場合、認証トークンの取得と管理は開発における重要なステップです。本記事では、YouTube Upload APIを例に、認証トークンを取得する実装方法について解説します。

    前提条件

    • Python 3.6以上の環境
    • Google Cloud Platformプロジェクトの作成済み
    • OAuth 2.0クライアントIDの取得済み
    • 必要なPythonライブラリのインストール pip install google-auth-oauthlib

    認証トークン取得の実装

    以下のコードは、Google Cloud APIの認証トークンを取得し、JSONファイルに保存する実装例です。

    from google_auth_oauthlib.flow import InstalledAppFlow
    import logging
    import json
    
    # デバッグ用にログレベルを設定
    logging.basicConfig(level=logging.DEBUG)
    
    # 必要なスコープを指定
    SCOPES = ['https://www.googleapis.com/auth/youtube.upload']
    CLIENT_SECRET_FILE = 'client_secret.json'
    
    def get_credentials():
        """
        OAuth 2.0認証フローを実行し、認証情報を取得する関数
        """
        flow = InstalledAppFlow.from_client_secrets_file(
            CLIENT_SECRET_FILE, SCOPES)
        
        # ローカルサーバーを起動して認証フローを実行
        creds = flow.run_local_server(
            port=57062,
            open_browser=True
        )
        
        # 必要な認証情報を辞書形式で返却
        return {
            'token': creds.token,
            'refresh_token': creds.refresh_token,
            'token_uri': creds.token_uri,
            'client_id': creds._client_id,
            'client_secret': creds._client_secret,
            'scopes': creds.scopes,
            'universe_domain': 'googleapis.com',
            'account': '',
            'expiry': creds.expiry.isoformat() + 'Z'  # ISO形式の日時文字列に変換
        }
    
    try:
        # 認証情報を取得
        credentials = get_credentials()
        
        # 認証情報をJSONファイルに保存
        with open('token.json', 'w') as f:
            json.dump(credentials, f, indent=4)
        
        print("認証トークン情報をtoken.jsonに保存しました。")
        
    except Exception as e:
        print(f"エラーが発生しました: {e}")

    コードの解説

    1. ライブラリのインポート

    from google_auth_oauthlib.flow import InstalledAppFlow
    import logging
    import json
    • google_auth_oauthlib:Google認証フローを扱うためのライブラリ
    • logging:デバッグ情報を出力するためのロギング機能
    • json:JSON形式のデータを扱うためのライブラリ

    2. ログレベルの設定

    logging.basicConfig(level=logging.DEBUG)

    開発中はDEBUGレベルでログを出力することで、認証プロセスの詳細な情報を確認できます。本番環境では、必要に応じてログレベルを調整しましょう。

    3. スコープと認証情報の指定

    SCOPES = ['https://www.googleapis.com/auth/youtube.upload']CLIENT_SECRET_FILE = 'client_secret.json'
    • SCOPES:アクセス権限の範囲を指定します。今回はYouTubeへの動画アップロード権限を要求しています。
    • CLIENT_SECRET_FILE:Google Cloud Consoleからダウンロードした認証情報のJSONファイル名を指定します。

    4. 認証情報取得関数

    def get_credentials():

    OAuth 2.0認証フローを実行し、認証情報を取得する関数です。

    4.1 認証フローの初期化

    flow = InstalledAppFlow.from_client_secrets_file(
        CLIENT_SECRET_FILE, SCOPES)

    クライアントシークレットファイルとスコープを指定して認証フローを初期化します。

    4.2 認証フローの実行

    creds = flow.run_local_server(
        port=57062,
        open_browser=True
    )
    • port=57062:ローカルサーバーのポート番号を指定します。
    • open_browser=True:認証フローをブラウザで自動的に開くオプションです。

    4.3 認証情報の整形

    return {
        'token': creds.token,
        'refresh_token': creds.refresh_token,
        'token_uri': creds.token_uri,
        'client_id': creds._client_id,
        'client_secret': creds._client_secret,
        'scopes': creds.scopes,
        'universe_domain': 'googleapis.com',
        'account': '',
        'expiry': creds.expiry.isoformat() + 'Z'  # ISO形式の日時文字列に変換
    }

    取得した認証情報を辞書形式で整形します。特に有効期限(expiry)はISO8601形式の文字列に変換しています。

    5. 認証情報の保存処理

    try:
        # 認証情報を取得
        credentials = get_credentials()
        
        # 認証情報をJSONファイルに保存
        with open('token.json', 'w') as f:
            json.dump(credentials, f, indent=4)
        
        print("認証トークン情報をtoken.jsonに保存しました。")
        
    except Exception as e:
        print(f"エラーが発生しました: {e}")

    認証情報を取得し、token.jsonファイルに保存します。エラーハンドリングも適切に実装されています。

    使用方法

    1. Google Cloud Consoleでプロジェクトを作成し、OAuth 2.0クライアントIDを取得します。
    2. 取得したクライアントID情報をclient_secret.jsonとして保存します。
    3. 上記のスクリプトを実行します。
    4. ブラウザが自動的に開き、Googleアカウントでの認証画面が表示されます。
    5. 認証が完了すると、トークン情報がtoken.jsonに保存されます。

    注意点

    1. セキュリティ: client_secret.jsontoken.jsonには機密情報が含まれるため、バージョン管理システムにコミットしないよう注意しましょう。.gitignoreファイルに追加することをお勧めします。
    2. トークンの有効期限: アクセストークンには有効期限があります。実際のアプリケーションでは、有効期限を確認し、必要に応じてリフレッシュトークンを使用して新しいアクセストークンを取得する処理を実装してください。
    3. 本番環境の考慮: このコードはローカル開発環境向けです。本番環境では、セキュリティを考慮した認証方法(サービスアカウントの利用など)を検討してください。

    まとめ

    本記事では、YouTube Upload APIを例に、Google Cloud APIの認証トークンを取得する方法を解説しました。OAuth 2.0認証フローを理解し、適切に実装することで、セキュアなAPIアクセスが可能になります。認証は一見複雑に思えますが、適切なライブラリを利用することで比較的簡単に実装できます。

    今回紹介したコードは基本的な実装例であり、実際のアプリケーションでは要件に応じてカスタマイズすることをお勧めします。認証情報の安全な管理と、トークンの更新処理などを適切に実装することで、より堅牢なアプリケーションを開発できるでしょう。

  • GCPで利用する鍵を変更する

    GCPで利用する鍵を変更する

    tl;dr;

    GCP で key を有効化する手順についてよく忘れるのでメモ。

    Activate

    service account によって払い出した key を読み込む

    gcloud auth activate-service-account --key-file xxxx.json 
    Activated service account credentials for: [xxxx@xxxx.iam.gserviceaccount.com]
    

    確認

    Cloud Storage に対する確認を行いたい場合、以下の様にアクセスする。

    gsutil ls gs://hogehoge-bucket/                

     

  • GCP(CloudStorage) で署名付き URL を作成する

    GCP(CloudStorage) で署名付き URL を作成する

    tl;dr;

    GCP(CloudStorage) で署名付き URL を作成する方法を紹介します。

    方法

    requirements.txt にoauth2client を記載します。

    oauth2client

    install します。

    pip3 install -r requirements.txt  

    python でスクリプトを書きます。今回は 120秒間だけ見せることにしました。

    import time
    import urllib 
    from datetime import datetime, timedelta 
    import os
    import base64 
    from oauth2client.service_account import ServiceAccountCredentials
     
    API_ACCESS_ENDPOINT = 'https://storage.googleapis.com'
     
    def sign_url(bucket, bucket_object, method, expires_after_seconds=120):
        gcs_filename = '/%s/%s' % (bucket, bucket_object)
        content_md5, content_type = None, None
     
        credentials = ServiceAccountCredentials.from_json_keyfile_name('xxxxxxxx.json')
        google_access_id = credentials.service_account_email
     
        expiration = datetime.now() + timedelta(seconds=expires_after_seconds)
        expiration = int(time.mktime(expiration.timetuple()))
     
        signature_string = '\n'.join([
            method,
            content_md5 or '',
            content_type or '',
            str(expiration),
            gcs_filename])
        _, signature_bytes = credentials.sign_blob(signature_string)
        signature = base64.b64encode(signature_bytes)
     
        query_params = {'GoogleAccessId': google_access_id,
                        'Expires': str(expiration),
                        'Signature': signature}
     
        return '{endpoint}{resource}?{querystring}'.format(
            endpoint=API_ACCESS_ENDPOINT,
            resource=gcs_filename,
            querystring=urllib.parse.urlencode(query_params))
     
     
    if __name__ == '__main__':
        url = sign_url('project-name', 'test/coco.png', 'GET')
        print(url)

    黄色で塗った部分が、主に変更する場所になります。

    結果

    python3 main.py                               
    https://storage.googleapis.com/project/test/coco.png?GoogleAccessId=signed-url%40project&Expires=1581540902&Signature=xxxx

     

    • 左側が有効期限内にアクセスした時に見える結果です
    • 右側が有効期限が過ぎた際に見える結果です

    参考情報

    https://cloudpack.media/45121