[google-oauth][python] Google APIs Client Library for Python

# google-oauth on python

OpenID Connectをpythonで実装してみる。
実装方法の理解のため、Googleのドキュメントを超訳する。

## OAuth 2.0 explained

OAuth 2.0の概要説明。省略。

## Acquiring client IDs and secrets

クライアントIDが3種類あるので、ご注意ください。

+ Web application client IDs
+ Installed application client IDs
+ Service Account client IDs

## The oauth2client library

**oauth2client**ライブラリはGoogle APIsClient Library（Python)に含まれています。このライブラリは、全てステップでAPIを呼ぶためのOAuth 2.0プロトコルを制御します。

## Flows

Flowクラスはユーザーデータにアクセスする認可をアプリに与えるものです。データ獲得のために必要な複数回のリダイレクト処理を、Flowオブジェクトの関数が助けます。Flowオブジェクトは認証情報を持つが使い捨てです。その認証情報は抽出して保存できます。Flowオブジェクトの使い方は色々あります。

### flow_from_clientsecrets()

**oauth2client.client.flow_from_clientsecrets()**は**client_secrets.json**ファイルからFlowオブジェクトを生成する。このJSONフォーマットファイルはクライアントID、クライアントシークレットとOAuth 2.0 パラメータを保存しています。

```python
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**クラスはインストールアプリとウェブアプリの両方で使えます。コンストラクタの引数はクライアントID、クライアントシークレット、スコープ、リダイレクトURIです。URIはあなたのアプリが制御するものでなければいけません。

```python
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()

認証サーバーのURIを生成します。URIの先で認証が終わるとリダイレクトする。

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

認可済みのユーザーの場合は、すぐさまサーバーはリダイレクトします。
未認証の場合は、認証サーバーはユーザーにデータアクセス許可を求めます。
ユーザーがあなたにデータアクセス権を与えたら、サーバーは**redirect_uri**は**code**クエリを持って返ります。

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

ユーザーがアクセスを許可しない場合、**redirect_uri**には**error**クエリが返されます。

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

### step2_exchange()

**step2_exchange()**関数はFlowクラスを**Credentials**オブジェクトに変更します。 認証サーバーが受けた**code**を引数に渡します。

```python
credentials = flow.step2_exchange(code)
```

## Credentials

Credentialsオブジェクトは一人のユーザーデータにアクセスする**リフレッシュトークン**と**アクセストークン**を保有します。このオブジェクトは*httplib2.Http*オブジェクトを適応してアクセス認可を受けます。適応は1度だけでよく、認証後は保存できます。Credentialsオブジェクトを生成するいくつかの方法を説明します。

### 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()

**Credentials**クラスの**authorize()**関数はhttplib2.Httpインスタンスから全てのリクエストへの認証ヘッダーを適用するのに使います。


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

httplib2.Httpオブジェクトが既に認証されていれば、一般的に**build**関数を使ってパスします。

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

## Storage

**oauth2client.client.Storage**オブジェクトは**Credentials**を保管したり引き出したりします。オブジェクト生成の方法と使い方を説明します。

### file.Storage

**oauth2client.file.Storage**クラスは1つの**Credentials**クラスを保管、引き出しできます。単一の保管物に対して並列処理をサポートしています。以下はファイルの開き方、Credentialsの保存方法、引き出し方です。

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