OAuth認証によるアクセスでは、以下のものが必要になります。
・OAuthクライアントID
・OAuthクライアントシークレット
・OAuth認証コード
・アクセストークン
・リフレッシュトークン
・スプレッドシートのID
実際にアクセスするのに必要なのはアクセストークンとスプレッドシートのIDのみです。
アクセストークンを取得するのにOAuth認証コードとクライアントシークレットもしくはリフレッシュトークンが必要になり、
OAuth認証コードやリフレッシュトークンを取得するにはOAuthクライアントIDが必要になります。
結構ややこしい。
注意なのは、アクセストークンには有効期限があり、切れるとそのトークンではアクセスできなくなることです。
その時はリフレッシュトークンを使って、アクセストークンを再発行することになります。
リフレッシュトークンに有効期限はない(多分)ので、どこかに保存しておきましょう。
スプレッドシートのIDは、スプレッドシートのURLの一部になります。
https://docs.google.com/spreadsheets/d/[この部分]/edit#gid=0
手順
OAuthのクライアントIDとクライアントシークレットをAPIConsoleから作る
当たり前ですが、Googleアカウントが必要になります。
Google API Consoleとググるとトップにサイトが出てきます。
そこで認証情報→認証情報を作成→OAuthクライアントの作成を選んでください。
アプリケーションの種類を聞かれるので、その他を選んで、名前は適当につけてください。
これでOAuthのクライアントIDとクライアントシークレットを取得できました。
Unityが登場するのはまだ先です。
OAuthのクライアントIDとScopeから、認証コードを取得する
認証コードを取得するには、クライアントIDとScopeが必要になります。
Scopeは、特定のサービスに、どの権限でアクセスするかを教えるものです。
今回はスプレッドシートの読み書きをしたいので、
https://www.googleapis.com/auth/spreadsheets
がScopeになります。
Scopeの種類は以下に書いてあるので、スプレッドシート以外のサービスにもアクセスできます。
OAuth 2.0 Scopes for Google APIs | Google Identity Platform | Google Developers
コードを取得するには、
https://accounts.google.com/o/oauth2/v2/auth にクエリをたくさんつけてリクエストを投げます。
クエリは、
?scope=https://www.googleapis.com/auth/spreadsheets
&redirect_uri=http://localhost
&response_type=code
&client_id=OAuthクライアントID
になります。
全部ひとつなぎにしてURL欄に入力してください。
URLが正しく入力できていると以下の画面に飛ぶので、許可を選んでください。
もしGoogleのアカウントにログインする画面に飛んだら、OAuthクライアントを作ったアカウントでログインしてください。
許可を押すとredirect_uriで設定した先へ飛んでいきます。
localhostにしたので何もないですが、URLのcode=~以下がOAuthの認証コードになるので保存しておきましょう。
認証コードからアクセストークンとリフレッシュトークンを取得する
ここからUnityでの作業になります。
UnityのWWWを使って、OAuthからスプレッドシートのアクセストークンをもらいましょう。
https://www.googleapis.com/oauth2/v4/token にフォームデータ付きでリクエストを送信します。
WWWForm form = new WWWForm ();
form.AddField ("code", OAuthの認証コード);
form.AddField ("client_id", OAuthクライアントID);
form.AddField ("client_secret", クライアントシークレット);
form.AddField ("redirect_url", "http://localhost");
form.AddField ("grant_type", "authorization_code");
form.AddField ("access_type", "offline");
form.headers.Add ("Content-Type", "application/x-www-form-urlencoded");
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW ("https://www.googleapis.com/oauth2/v4/token", rawData, headers);
レスポンスはwww.textにJSON形式で入って返ってきます。
こんなJSONが返ってきたら成功です。
{
"access_token": "アクセストークン",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "リフレッシュトークン"
}
expires_inがアクセストークンの有効期限で、スプレッドシートは1時間のようです。
リフレッシュトークンは数に上限があるそうなので、なるべく同じのを使い続けましょう。
Unityからでなくても、curlコマンドを使うと同じことが出来ます。
その方法は他の人が書いてるので割愛。
このシートのデータを取ってきてみましょう。
テイルズオブベルセリアのキャラです。面白かったです。
ここまで来ると簡単で、
https://sheets.googleapis.com/v4/spreadsheets/スプレッドシートのID/values/取得するセルの範囲?AccessToken=アクセストークン
にPOSTすると、セルの中身がJSON形式で返って来ます。
WWW www = new WWW ("https://sheets.googleapis.com/v4/spreadsheets/スプレッドシートのID/values/取得するセルの範囲?AccessToken=アクセストークン");
今回はセルの範囲をA1:B4にしました。
{
"range": "'シート1'!A1:B4",
"majorDimension": "ROWS",
"values": [
[
"名前",
"性別"
],
[
"ベルベット",
"女"
],
[
"ライフィセット",
"男"
],
[
"ロクロウ",
"男"
]
]
}
無事取ってこれたでしょうか。
後はJSONをMiniJSONとか使って保存すればOKですね!
リフレッシュトークンからアクセストークンを取得する
先程も書きましたが、アクセストークンには有効期限があるので、もし切れていたら、リフレッシュトークンを使って再発行する必要があります。
https://www.googleapis.com/oauth2/v4/tokenにリクエストを飛ばすと取得できます。
WWWForm form = new WWWForm ();
form.AddField ("refresh_token", リフレッシュトークン);
form.AddField ("client_id", OAuthクライアントID);
form.AddField ("client_secret", OAuthクライアントシークレット);
form.AddField ("grant_type, "refresh_token");
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW ("https://www.googleapis.com/oauth2/v4/token", rawData);
これで成功していたら、アクセストークンがJSON形式で返ってきます。
アクセストークン期限が切れていなくても再発行可能のようです。
10個くらい連続で取得してみたのですが、全部使えました。
アクセストークンが有効かどうか調べる
有効かどうか、また有効期限も調べられます。
WWW www = new WWW("https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=アクセストークン");
無効だった場合
{
"error_description": "Invalid Value"
}
※もともと存在しない適当な文字列入れても同じエラーが返ってきます。
有効だった場合(例)
{
"azp": "247046462806-7efg42ut1tau4n2ku081gn81nebma2ab.apps.googleusercontent.com",
"aud": "247046462806-7efg42ut1tau4n2ku081gn81nebma2ab.apps.googleusercontent.com",
"scope": "[]https://www.googleapis.com/auth/spreadsheets[]",
"exp": "1485228014",
"expires_in": "3584",
"access_type": "offline"
}
Unityの記事と言いましたが、認証の仕方は他でも使えると思います。
間違っていたり、質問や不明点がありましたらコメントでお願いします。