概要
google-api-javascript-client を使ってみました
OAuth の実行方法と認証後にセッショントークンを使って Compute の API をコールするところまで試してみました
環境
- macOS 10.15
- google-api-javascript-client (2019/11/05 時点)
アプリ雛形作成
bundle init
vim Gemfile
gem "sinatra"
bundle install --path vendor
vim config.ru
require './app'
run TestWebApp
vim app.rb
require 'sinatra/base'
class TestWebApp < Sinatra::Base
get '/' do
erb :index
end
end
mkdir views
touch views/index.erb
OAuth クライアントの作成
まずはおなじみに OAuth クライアントの作成から行います
作成したらクライアントID とクライアントシークレットをメモしましょう
JavaScript の SDK の場合クレデンシャルファイルを使った認証はできないので文字列の ID とシークレットを使います
OAuth だけ実装してみる
では先に OAuth だけ実装してみましょう
作成した erb
ファイルに実装していきます
vim views/index.erb
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script type="text/javascript">
var PROJECT_ID = 'pjct-1234';
var CLIENT_ID = '123456789012-asdfghjklqwertyuiopzxcvbnm.apps.googleusercontent.com';
var API_KEY = 'api-key';
var SCOPES = 'https://www.googleapis.com/auth/compute';
function authorization() {
gapi.client.setApiKey(API_KEY);
gapi.auth.authorize({
client_id: CLIENT_ID,
scope: SCOPES,
immediate: false
}, function(authResult) {
console.log(authResult.access_token);
if (authResult && !authResult.error) {
$('#ret').text('success');
} else {
$('#ret').text('error');
}
});
}
$(window).load(authorization);
</script>
</head>
<body>
<p id="ret"></p>
</body>
</html>
PROJECT_ID
は自身の使っているプロジェクトの ID を設定してください
CLIENT_ID
, API_KEY
は先程メモしておいたものを使ってください
解説
まず SDK を読み込みます
<script src="https://apis.google.com/js/client.js"></script>
今回は JQuery も使っています
次に OAuth の処理を実装します
gapi.client.setApiKey
で API_KEY をセットします
そして gapi.auth.authorize
を使って認証します
今回はスコープに compute の API をコールするためのスコープを追加しています
immediate
パラメータは true にすると動作しなかったのでとりあえず false にしています
true にすると認証時にポップアップが表示されないようなのですが動作しなかったので false にしています
あとは認証後のコールバックの関数部分を実装しています
今回は認証の結果だけを表示しています
authResult オブジェクトにセッショントークンの情報が入っています
実際に compute の API をコールするときはこの authResult オブジェクトから勝手に access_token
を取得してコールしてくれるので意図的に参照するケースはないかなと思います
動作確認
bundle exec rackup config.ru
http://localhost:9292
にアクセスすると認証用のポップアップが表示されます
おそらくポップアップがブロックされるので許可して動作確認しましょう
localhost からのアクセスなので警告がでますがテストなので無視します
あとは「success」と表示されれば認証完了です
コンソールにも authResult の情報が表示されているのが確認できると思います
Compute の API をコールする処理を追加
セッショントークンが取得できたら Compute の API をコールしてみましょう
vim views/index.erb
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script type="text/javascript">
var PROJECT_ID = 'pjct-1234';
var CLIENT_ID = '123456789012-asdfghjklqwertyuiopzxcvbnm.apps.googleusercontent.com';
var API_KEY = 'api-key';
var SCOPES = 'https://www.googleapis.com/auth/compute';
var API_VERSION = 'v1';
var DEFAULT_PROJECT = PROJECT_ID;
var DEFAULT_ZONE = 'us-central1-c';
var DISCOVERY_DOCS = ['https://www.googleapis.com/discovery/v1/apis/compute/v1/rest'];
function authorization() {
gapi.client.setApiKey(API_KEY);
gapi.auth.authorize({
client_id: CLIENT_ID,
scope: SCOPES,
immediate: true
}, function(authResult) {
if (authResult && !authResult.error) {
$('#auth_ret').text('success');
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
client_id: CLIENT_ID,
scope: SCOPES
}).then(function() {
var request = gapi.client.compute.instances.list({
'project': DEFAULT_PROJECT,
'zone': DEFAULT_ZONE
});
request.execute(function(resp) {
$('#ret').text('success');
resp.items.forEach(function(i) {
$('#instances').append("<li>" + i.name + "</li>");
});
});
})
.catch(function() {
$('#ret').text('error');
});
} else {
$('#auth_ret').text('error');
}
});
}
$(window).load(authorization);
</script>
</head>
<body>
<h1>Auth</h1>
<p id="auth_ret"></p>
<h1>Compute API</h1>
<p id="ret"></p>
<ul id="instances"></ul>
</body>
</html>
デフォルトのゾーンを調べる方法は以下のコマンドを実行しましょう
gcloud compute project-info describe --project pjct-1234
デフォルトゾーンが設定されていない場合は自分のインスタンスが存在しているゾーンを設定しましょう
解説
認証後のコールバックメソッドに compute の API をコールする処理を追加しています
今回はすべて同じメソッド内で実装していますが分けても問題ないです
まず gapi.client.init
で Compute の API をコールするためのクライアントを初期化します
初期化する際には discoveryDocs
という API の定義が配布されている URL があるのでこれを指定します
Compute API の場合は https://www.googleapis.com/discovery/v1/apis/compute/v1/rest になります
次にクライアントの初期化が完了したら API をコールします
gapi.client.compute.instances.list
というメソッドを使います
client のあとに「API 名」「リソース名」「操作名」という規則でコールすることができます
引数などは操作名ごとにことなるのでリファレンスを確認してください
最後に結果を受け取ってそれを HTML に表示して終了です
レスポンスの形式は一度 cosole.log などで覗いてみると扱いやすいと思います
ハマリポイント
gapi.client.load
は Deprecated になっておりクライアントを初期化する場合は gapi.client.init
+ discoveryDocs を使いましょう
自分はこの方法にたどり着くまでに「gapi.client.compute is undefined」というエラーにずっと悩まされました
実は gapi.client.load
が正常に行われていないために gapi.client.compute
が生成されていないのが原因でした
動作確認
bundle exec rackup config.ru
http://localhost:9292
にアクセスすると認証用のポップアップが表示されます
すでに認証済みの場合はすぐにポップアップが閉じると思います
しばらくすると以下のようにインスタンスの情報が表示されると思います
最後に
google-api-javascript-client を使って OAuth 処理の実装と Compute API のコールをしてみました
情報があまりなく Compute API をコールするときに少しハマりました
HTML と JavaScript だけで完結するのでサーバが不要な場合に使える方法かなと思います
0 件のコメント:
コメントを投稿