サービスアカウント JWT を使って Google Spreadsheets APIにアクセスするための手順（CData ODBC Driver for Google Spreadsheets）

Google の API では主な認証方法として通常のOAuthを利用したフローとサービスアカウントを利用した JWT（Json Web Token）を方式の2種類が提供されています。（GmailですとBasicもありますが）

ベーシックな方法としては前者のOAuthかと思いますが、シチュエーションによっては後者のほうが望ましい場合も多々あります。ですが、後者を解説している記事があまり見当たらないので、まとめてみました。

JWT は Google の APIであれば、どれでもアクセスできるように構成できますが、今回はよく質問されることが多い Google Spreadsheets API へアクセスするという想定で書いています。

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

JWTにはサービスアカウントと呼ばれる、独自のアカウント情報が必要になるので、まずはこのサービスアカウントを準備します。

あらかじめGCPのアカウントが必要になるので、注意しましょう。

GCP コンソールに移動し対象とするプロジェクトを開きます。

https://console.cloud.google.com/home/dashboard

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/43f40859-6854-c30c-9f64-982b93722872.png)

対象のプロジェクトを構成していない場合は、「新しいプロジェクト」をクリックし

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/8b9479c5-5e77-f881-6db8-6c897cdfdad9.png)

任意の内容でプロジェクトを作成してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/be26da80-9be2-7430-9457-fbdd9270ed35.png)

対象のプロジェクトを作成後「APIとサービス」から「認証情報」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/85020edb-0cd5-9359-c590-ab57af49ea99.png)

「認証情報を作成」→「サービスアカウント キー」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/587c9389-5f7e-d5e6-8459-ad0ae1cfdb3a.png)

新しいサービスアカウントで任意の「サービス アカウント名」と「サービス アカウントID」を入力し、キーのタイプから「P12」を選択して、作成をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/f060d3e0-d63a-8fa3-f3be-2bb2e58e55a3.png)

今回はGoogle Spreadsheets APIのため、役割は指定しませんが、BigQuery APIなどを利用したい場合は必要に応じて役割を設定します。

設定後、P12の証明書がダウンロードが開始されるので、任意のフォルダに保存してください。また、P12証明書をインストールする際のパスワードも表示されるので控えておきましょう。

# P12証明書のインポート

次にダウンロードした証明書をインポートします。

ウィザードに従って設定するだけなので、特に難しいことはありません。会社マシンの場合推奨事項があるかもしれないので、そこは情シスなどへの確認が必要かと思います。

保存場所は任意の場所を選択してください。今回は「現在のユーザー」を選択しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/f2cfbf7a-1f2b-a8ca-b17b-37f48e7785b0.png)

パスワードは先程サービスアカウントを作成した際に表示されたパスワードになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/1eef70b7-f04f-67b1-853b-76699408e192.png)

証明書ストアはデフォルトで進めて問題ありません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/97d276d1-893d-030f-137f-1af04835c326.png)

以上で、証明書のインポートが完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/b03b33b1-e920-685f-a59f-2866a4f5d0b0.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/1a16b546-ab3e-a38a-13e2-942079672251.png)

# API アクセス権限の付与

次に一度GCPの画面に戻り、作成したプロジェクトへAPI アクセス権を付与します。

「APIとサービス」のメニューから「ライブラリ」を選択し

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/fd34510b-501a-8b2f-355f-339b218129f1.png)

一覧の中から必要なAPIのアクセス権を設定します。Google Spreadsheetで一つ注意したいのが、「SpreadsheetはGoogle Driveに保存されている」ということです。

そのため、Google Spreadsheet APIを利用する場合は「Google Drive API」と「Google Sheets API」の2つのAPI を有効化する必要があるので注意しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/9791cbe0-f44d-8eea-9e53-79a3a9e940b1.png)

以下のようにそれぞれ、「有効にする」をクリックすればOKです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/ad63a133-183d-80c7-bdb6-11e59775332b.png)

# Google Sheet をJWTサービスアカウントでアクセスさせる場合

それでは実際にAPIを試したいと思いますが、事前にアクセスしたいGoogle Sheetを作成しておきましょう。

今回は以下のようなGoogle Sheetを個人アカウント（サービスアカウントではない）で作成しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/0d526a98-3a92-7304-7556-4581a961ee31.png)

さて、一つ注意しなければいけないのは、「APIアクセス可能なGoogle SheetはそのアカウントのGoogle Driveに保存された、もしくは共有されたGoogle Sheetが対象になる」ということです。

つまりサービスアカウントがアクセスできるGoogle Sheetでなければいけません。

今回は私の個人アカウントで作成したので、このGoogle Sheetに先程作成したサービスアカウントに対して共有設定を行うことで、APIアクセスを可能にします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/49bb2fe5-5b23-db3a-bce6-b3cf512b6b59.png)

共有の画面を開き、作成したサービスアカウントのアドレスを入力することで、設定は完了できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/7ce3c605-d97b-266e-8798-117d826daa57.png)

# CData ODBC Driverでアクセス

それでは、Google Sheet APIを実際に利用してみましょう。

今回はGoogle Spreadsheetを手軽に扱うことができる「CData ODBC Driver for Google Spreadsheets」を使って、アクセスしてみたいと思います。

以下のサイトから評価版ビルドをダウンロードします。

- [CData ODBC Driver for Google Spreadsheets](http://www.cdata.com/jp/drivers/gsheets/odbc/)

ダウンロードされたインストーラ形式(.exe)のファイルを起動します。
(注)ODBCデータアドミニストレーターを閉じてから実行してください。
(注)途中オンラインでのアクティベーションが実行されるためインターネットアクセス出来る環境で行ってください。

下記のようなインストーラが起動するので、ライセンス契約書を確認した上で、デフォルト設定のままインストールを進めて完了させます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/3a8f3be1-4828-f1a6-190a-1a8674eb16fa.png)


インストールが完了するとデフォルトブラウザが起動して製品ヘルプファイルが起動します。

また、ODBCのDSN構成ダイアログが表示されるので、以下のように設定を行います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/aee4e333-e071-a878-cb8f-ac4c0e354632.png)

（注）ODBCデータソースアドミニストレーターはマシンのビット数（32bit, 64bit）にあった方をご利用ください。

| 接続情報 | 設定項目 | 備考 | 
|:-----------------|------------------|------------------|
| OAuthJWTCertType | PFXFILE | デフォルト | 
| OAuthJWTCertPassword |Password |.p12を登録する時に利用したパスワード |
| OAuthJWTCertSubject |*| デフォルト |
| OAuthJWTIssuer |ServiceAccountName@ProjectName.iam.gserviceaccount.com| 作成したサービスアカウントアドレス |
| OAuthJWTCert |C:\Work\JWT\P12FileName.p12 | P12証明書の保存場所 |

「接続テスト」ボタンをクリックします。下記のようなダイアログが表示されれば成功です。「ODBCのDSN構成」の「OK」ボタンをクリックして保存します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/8f3b7e2b-3381-eeb7-35bf-87fc8992a158.png)

それでは Power Shellを使って、アクセスしてみたいと思います。以下のようなプログラムでレコードを取得してみました。

```ps

Set-StrictMode -Version Latest

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Data")

# 作成したDSNを指定
$connectionsString = "DSN=Google Sheet JWT" 
$odbcCon = New-Object System.Data.Odbc.OdbcConnection($connectionsString)
$odbcCon.Open();

$odbcCmd = New-Object System.Data.Odbc.OdbcCommand
$odbcCmd.Connection = $odbcCon

# コマンド実行（SELECT）
$odbcCmd.CommandText = "SELECT * FROM Sample_Sheet1"
$odbcReader = $odbcCmd.ExecuteReader() 

while ($odbcReader.Read()) {
    $odbcReader["Id"].ToString() + " " + $odbcReader["Name"].ToString()
}

$odbcCmd.Dispose()

$odbcCon.Close()
$odbcCon.Dispose()

```

コンソールに先程作成したSpreadsheetのデータが出力できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/9a9bec74-aae1-2279-1286-c3362ea6c415.png)

# G Suite ドメイン全体の委任を有効にする場合

場合によっては、対象のGmailアカウントの権限を委譲したい場合もあるかと思います。その場合は、サービスアカウントに対してG Suite ドメイン全体の委任を有効にする必要があります。

その場合は、作成したサービスアカウントの一覧から「サービスアカウントの管理」へ移動し

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/7b8d42b3-2617-4fbb-f590-96d70d3c7a1e.png)

対象のサービスアカウントの「編集」を行います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/69d3098c-de3f-79ed-abe7-53844ac9288d.png)

ここで「G Suite ドメイン全体の委任を有効にする」にチェックを入れ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/acbaa844-861a-4767-8561-04b015e555bf.png)

任意のプロダクト名を入力します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/56301/4acfea64-9d2c-2488-5ae8-40f356e01529.png)

以上で、サービスアカウントにG Suite ドメイン全体の委任が有効化されます。

CData Driverでこの機能を利用して、対象のメールアドレスで代理アクセスを行う場合は、以下のOAuthJWTSubjectに追加で情報を入力します。

| 接続情報 | 設定項目 | 備考 | 
|:-----------------|------------------|------------------|
| OAuthJWTSubject | 対象のメールアドレス | デフォルト | 

# おわりに

いかがでしたでしょうか。

ちょっと取っつきづらいJWTですが、社内システムなどでAPIを利用する以上特定ユーザーのアカウントに依存してしまうのは避けたいシチュエーションが多いかと思います。

その場合は、ぜひ有効活用してみてください。