mizzsugar’s blog

日々感じていることや学んだことを書きます。エンジニアリング以外にも書くかもしれません。

【非公式翻訳】Google API Client Libraries > Python

公式の日本語版がなかったので、備忘録的に・・・

※2017/02/17が最終更新の記事となります。 ※表現するのが難しかったので図中の語句の訳は書きませんでした。 ※わかりづらい箇所や間違えている箇所がありましたら、コメント欄にてご指摘お願いします。

developers.google.com


OAuth 2.0

このドキュメントはOAuth 2.0を説明してます。OAuth 2.0を利用する際に、どのようにクライアントIDを取得するのか、どのようにPythonGoogle API クライアントのライブラリと利用するかを説明します。


OAuth 2.0とは

OAuth 2.0は、Google APIに利用される認証プロトコルです。このライブラリーのドキュメントの認証に関するページにようやくされています。また、他にも良い参照ページがあります。

プロトコルは複雑な問題を解決するため、理解するのが難しいかと存じます。

このプレゼンはプロトコルの重要な概念と、各ステップでライブラリをどのように利用するかを説明します。


ーーーーー

※プレゼンテーションスライドの翻訳。

(1枚目) OAuth 2.0とPythonのためのGoogle API クライアント

(2枚目) OAuth 2.0では、プロトコルが少々複雑です。

(3枚目) OAuth 2.0は、トリッキーな問題を解決しようとしています。

(4枚目) あなた(開発者)がアプリケーションをビルドしようとする際、

(5枚目) もしあなたのユーザーが

(6枚目) あなたのアプリケーションが機能するために必要な、他のサービス内にあるデータを持っているとすると

(7枚目) ー例えば、彼らのタスクリストや写真のような

(8枚目) どのようにそのデータを取得すればよいでしょうか?

(9枚目) あなたはユーザーに名前とパスワードを要求することができます。

(10枚目) しかし、そうしますと、ユーザーは そのサービス内にある彼らのデータすべてに対するアクセス権を あなたのアプリケーションに提供してしまいます。 それは安全ではありません。それはしないでください。

(11枚目) 名前とパスワードは彼らの電子上に保管されているすべての情報のキーのようなもので、それらをユーザーに要求すべきではありません。

(12枚目) 我々が本当に欲しているものは、APIの限られたデータへのみアクセスを認証する特別なキーです。

(13枚目) 特別なキーは、名前もパスワードも使わずに、アプリケーションを利用できるよう 要求することができます。

(14枚目) その仕組みが機能するためには、API・ユーザー・アプリケーションの全員が、「自分はーーーである」と述べている通りの者であるかをそれぞれ確かめなければなりません。

(15枚目) それが、この複雑さの由来となります。

(16枚目) 実は先程の説明よりももう少し複雑です。なぜなら、その特別なキーは

(17枚目) データをセキュアな状態に保つために何回も変化するからです。

(18枚目) ようやく OAuth 2.0がどのようなものかが分かりました。それはPythonGoogle API クライアントではどのように機能するのでしょうか?

(19枚目) そのキーはCredentialsオブジェクトの中にあります

(20枚目) Credentialsを得るためにはFlowオブジェクトを通さなければなりません。

(21枚目) 最終的に、キーは何回も変化するため、キーを保持し、取り出すためのStorageオブジェクトがあります。

(22枚目) セットアップし、Flowオブジェクトを実行することでCredentialsオブジェクトを生成し、Storageオブジェクトに生成したCredentialsオブジェクトを保管します。

(23枚目) 後々、キーが必要になった時、Storageオブジェクトから取り出し、利用することができます。

(24枚目) この画像の図よりもシンプルだと思っていただけると嬉しいです。

(25枚目) 実際のコードを見てみましょう。

(26枚目) まず、Flowオブジェクトを生成します。

(27枚目) Google APIでは、あなたのアプリケーション用のクライアントIDと秘密鍵を作成するために

http://code.google.com/apis/console

にアクセスする必要があります。

(28枚目) Flowを立ち上げます。

(29枚目) Flowが終了した時に、Credentialsを取得します。それをStorageに保管します。

(30枚目) Credentialsを利用するために、Storageから取り出し、httplib2.Http()オブジェクトCredentialsを適用します。

(31枚目) httpで作られたあらゆるHTTPリクエストは、これらのCredentialsによって認証されます。

(32枚目) プラットフォームごとにStorageクラスがあります。

(33枚目) より簡単にするために、Appエンジンを助ける方法もあります。

(34枚目) デコレーターを載せると、デコレーターによってFlows, Storage, Credentialsが利用されます。

(35枚目) oauth_requiredは最もシンプルに利用できるインターフェースある一方、oauth_awareが推奨されているインターフェースです。

(36枚目) ユーザーのデータへのアクセスをリクエストしている理由の説明をユーザーに弁明するために、linkを設置することができます。

(37枚目) 以上が概要となります。より詳細な情報は下記をご参照ください。

より詳しい情報がWikiにあります。

https://developers.google.com/api-client-library/python/guide/aaa_oauth

説明したクラスに関するPyDocはこちら

OAuth2WebServerFlow

Credentials

StorageByKeyName

OAuth2Decorator

※上記4つにアクセスしたところ、404エラーになってしまいました。

ーーーーー


クライアントIDと秘密鍵を取得する

Google APIs ConsoleのAPI Access paneでクライアントIDと秘密鍵を取得できます。異なる種類のクライアントIDがあるため、あなたのアプリケーションにとって正しい種類のものを取得するに気をつけましょう。

  • WebアプリケーションのクライアントID
  • インストールアプリケーションのクライアントID
  • サービスアカウントのクライアントID


注意: 秘密鍵が外にもれないようにしてください。もし他の誰かがあなたの秘密鍵を取得したら、あなたのクォータを消費し、Google API Consoleプロジェクトの変更を突破し、ユーザーのデータにアクセスするようリクエストを送る可能性があります。


oauth2clientライブラリ

oauth2clientライブラリはPythonGoogle API Client ライブラリに含まれています。それは、APIを呼ぶのに必要なOAuth 2.0のプロトコルのすべてのステップを扱います。OAuth 2.0ライブラリのみ必要である場合、分離したパッケージとして利用することも可能です。下記の段落では、このライブラリで重要なモジュール、クラス、機能を説明します。


Flows

Flowクラスの目的は、あなたのアプリケーションがユーザーのデータにアクセスすることを認証するための認証情報を得ることです。ユーザーがアクセスを認証するには、OAuth 2.0のステップはあなたのアプリケーションに、潜在的に複数回ブラウザにリダイレクトすることを要求します。Flowオブジェクトには、あなたのアプリケーションがこれらのステップを踏んで認証情報を得ることを助ける機能があります。Flowオブジェクトは一時的なものであり、Credentialsを生成すると捨てられる可能性があります。ただし、それらは保存(pickle)されたり保管されることもできます。


★メモ:プラットフォーム特有のFlowのための「Google App Engineを利用する 」「Djangoを利用する」のページをご覧ください。


flow_from_clientsecrets()

oauth2client.client.flow_from_clientsecrets() メソッドは、 client_secrets.jsonファイルからFlowオブジェクトを生成します。この形式のJSONファイルはクライアントID、秘密鍵、OAuth 2.0のパラメータを保管しています。

下記は、Flowオブジェクトを作成するためにどのようにflow_from_clientsecrets() を利用するかを示します。

from oauth2client.client import flow_from_clientsecrets
...
flow = flow_from_clientsecrets('path_to_directory/client_secrets.json',
                               scope='https://www.googleapis.com/auth/calendar',
                               redirect_uri='http://example.com/auth_return')


OAuth2WebServerFlow

名前にそぐわず、oauth2client.client.OAuth2WebServerFlow クラスはイントールアプリケーションにもWebアプリケーションにも利用できます。OAuth2WebServerFlowオブジェクトは、クライアントID・秘密鍵・そのコンストラクタへのスコープをパスすることで生成されます。: あなたはredirect_uriパラメータでコンストラクタを提供します。これはあなたのアプリケーションが扱っているURIでなければなりません。

from oauth2client.client import OAuth2WebServerFlow
...
flow = OAuth2WebServerFlow(client_id='your_client_id',
                           client_secret='your_client_secret',
                           scope='https://www.googleapis.com/auth/calendar',
                           redirect_uri='http://example.com/auth_return')


step1_get_authorize_url()

Flowクラスのstep1_get_authorize_url() ファンクションは認証サーバのURIを生成するために利用されます。 認証サーバのURIをもつと、ユーザーがそこにリダイレクトします。下記は、このファンクションを呼び出す一例です。

auth_uri = flow.step1_get_authorize_url()
# Redirect the user to auth_uri on your platform.

ユーザーが以前にあなたのアプリケーションへのアクセスが認証されていたら、認証サーバはただちにredirect_uriにリダイレクトします。ユーザーがまだアクセスが認証されていなかったら、認証サーバはあなたのアプリケーションにアクセスしても良いか訪ねます。アクセスを認証したら、下記のようなcodeクエリの文字列パラメータをもったredirect_uriにリダイレクトします。

http://example.com/auth_return/?code=kACAH-1Ng1MImB...AA7acjdY9pTD9M

アクセスを拒否したら、下記のようなエラークエリの文字列パラメータをもったredirect_uriにリダイレクトします。

http://example.com/auth_return/?error=access_denied


step2_exchange()

Flowクラスのstep2_exchange() ファンクションは、Credentialsオブジェクトの認証コードを交換します。このファンクションに認証サーバのリダイレクトで得たコードを渡してください。

credentials = flow.step2_exchange(code)


Credentials

Credentialsオブジェクトは、単一のユーザーデータへのアクセスを認証するリフレッシュトークンとアクセストークンを保持します。これらのオブジェクトは、アクセスを認証するhttplib2.Httpオブジェクトに適用されます。一度だけ適用すればよく、それらは保管されることができます。この段落ではCredentialsオブジェクトを 生成・利用するための様々なメソッドを説明します。

★メモ:プラットフォーム特有のFlowのための「Google App Engineを利用する 」「Djangoを利用する」のページをご覧ください。


OAuth2Credentials

oauth2client.client.OAuth2Credentials クラスは、ユーザーのデータへのアクセスを認証する、OAuth 2.0の認証情報をもっています。通常、コンストラクタを呼んでこのオブジェクトを生成しません。Flowオブジェクトが生成します。


ServiceAccountCredentials

oauth2client.service_account.ServiceAccountCredentialsクラスは、OAuth 2.0 Service Accountsでしか利用されません。エンドユーザーはサーバー間のAPIの呼び出しに関わりません。そのため、Flowオブジェクトなしで直接このオブジェクトを生成することができます。


AccessTokenCredentials

oauth2client.client.AccessTokenCredentialsクラスは他の方法によってアクセストークンを既に取得している時に利用されます。Flowオブジェクトなしでこのオブジェクトを生成できます。


authorize()

必要な認証ヘッダーをhttplib2.Httpインスタンスによって作成されたすべてのリクエストへに適用するには、 Credentialsクラスのauthorize()ファンクションを利用してください。:

import httplib2
...
http = httplib2.Http()
http = credentials.authorize(http)

一度httplib2.Httpが認証されたら、それは一般的にビルドファンクションに渡されます。

from apiclient.discovery import build
...
service = build('calendar', 'v3', http=http)


Storage

oauth2client.client.Storageオブジェクトは、Credentialsオブジェクトを保管し、取り出します。この段落では、Storageオブジェクトを生成・利用する様々なメソッドを説明します。


★メモ:プラットフォーム特有のFlowのための「Google App Engineを利用する 」「Djangoを利用する」のページをご覧ください。


file.Storage

oauth2client.file.Storageクラスは単一のCredentialsオブジェクトを保管し、取り出します。このクラスは複数のプロセスやスレッドが単一のストアをオペレーションできるようなロックをサポートします。下記は、どのようにファイルを開き、Credentialsをファイルに保管し、これらの認証情報を取得するのかを示します。

from oauth2client.file import Storage
...
storage = Storage('a_credentials_file')
storage.put(credentials)
...
credentials = storage.get()


multistore_file

oauth2client.contrib.multistore_file モジュールを利用すると、複数の認証情報を保管することができます。認証情報は下記によって識別されます。

  • クライアントID
  • ユーザー情報
  • スコープ


keyring_storage

oauth2client.contrib.keyring_storage モジュールは、パスワードマネージャーを利用できる場合、単一のCredentialsオブジェクトをパスワードマネージャーの中に保管させることができます。認証情報は下記によって識別されます。

  • クライアントアプリケーションの名前
  • ユーザーネーム
from oauth2client.contrib.keyring_storage import Storage
...
storage = Storage('application name', 'user name')
storage.put(credentials)
...
credentials = storage.get()


Command-line tools

oauth2client.tools.run_flow() ファンクションは、コマンドラインアプリケーションが認証情報を取得するために利用されます。Flow引数は、ユーザーのデフォルトのWebブラウザーにある認証サーバのページを開こうとします。認証サーバはユーザー にあなたのアプリケーションがユーザーのデータにアクセスしてよいか訪ねます。もしユーザーがアクセスを許可したら、run()ファンクションが新しい認証情報を返します。新しい認証情報はStorage引数に保管され、そのStorageオブジェクトに関連したフィアルをアップデートします。

oauth2client.tools.run_flow()ファンクションは、コマンドラインのフラグによって制御されます。Pythonの標準ライブラリのargparse モジュールは、あなたのプログラムの最初に初期化されなくてはなりません。argparseはPython 2.7以上に含まれており、それ以前のバージョンではseparate packageとして利用可能です。下記は、どのようにこのファンクションを利用するかを示します。

import argparse
from oauth2client import tools

parser = argparse.ArgumentParser(parents=[tools.argparser])
flags = parser.parse_args()
...
credentials = tools.run_flow(flow, storage, flags)


特に記載のない限り、このページのコンテンツは クリエイティブ・コモンズの表示 3.0 ライセンス により使用許諾されます。サンプル コードは Apache 2.0 ライセンス により使用許諾されます。詳しくは、Google のサイトに関するポリシーをご覧ください。JavaOracleアフィリエイトのトレードマークに登録されています。

最終更新日 2017年2月17日