私は、gapi.auth.authorize を介して OAuth 2.0 を使用して Google+ ユーザーを認証し、gapi.client.request を使用して Google Fusion Tables sqlGet クエリを実行するページを書いています。クエリは認証前は正常に実行されますが、認証後 30 秒以上実行すると 403 "Insufficient Permission" エラーで失敗します。
この問題は、次のページで示されています: https://googledrive.com/host/0B5Urq1jZb1MYSWloU3NTY2M4Qnc/test3b.htm
次の手順に従ってください。
[クエリ] をクリックして、gapi.client.request Google Fusion Table SQL-get クエリを実行し、行数を返します。これは、ステップ 2 と 3 で OAuth が使用されるまで正常に実行されます。
[OAuth を開始] をクリックして、Google+ に対して immediate:true 承認を実行します。現在 Google+ にサインインしている場合、ユーザー名と ID が 3 番目のボタンに表示されます。
3 番目のボタンに Google+ ユーザー名が表示されない場合は、ボタン (「承認」) をクリックして Google+ にサインインします。
もう一度「クエリ」ボタンをクリックします。OAuth 認証から約 30 秒以内にクエリを押すと、クエリはエラーなしで実行されます。その後、クエリは 403 エラーで失敗します。なぜ?
デモページのソースは次のとおりです。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<title>Test3b</title>
<style type="text/css">
</style>
<script src="scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
var g_domIsReady = false;
var g_gapiIsReady = false;
$(function () {
log("@$(function())");
g_domIsReady = true;
start();
});
function gapiIsReady() {
log("@gapiIsReady");
g_gapiIsReady = true;
start();
}
function start() {
// Make sure both the gapi.client and the DOM (per jquery) are ready.
if (!(g_gapiIsReady && g_domIsReady)) return;
// Define members.
log("@start - gapi and DOM are ready");
var m_apiKey = "AIzaSyAvb0NHQMwyPbMJRtz2zRL4wTiVjZDiois"; // Points to Google account (including Google Drive) at paloalto@geodesy.net.
var m_clientId = "868768273487-q295tdfr54uvo98v74891qakcr9ci0pf.apps.googleusercontent.com";
var m_scopes = "https://www.googleapis.com/auth/plus.me";
// Wire buttons.
var queryButton = document.getElementById('query-button');
queryButton.onclick = function () { runGetRequest(); return false; };
var startOAuthButton = document.getElementById('startOAuth-button');
startOAuthButton.onclick = function () { startOAuth(); return false; };
// Set-up the gapi.
gapi.client.setApiKey(m_apiKey);
//----------------------------------------------------------------------------
// gapi.client.request query functions.
//----------------------------------------------------------------------------
function runGetRequest() {
log("@runGetRequest");
var tableId = "1VZgvKyuh9uHXkQawpxg1MU8AlO8Mngl-sx7SP74"; // TR_TREE_E
var sql = "select count(GID) from " + tableId + " where GID > 50000";
var path = "/fusiontables/v1/query";
var restRequest = gapi.client.request({
path: path,
params: { 'sql': sql }
});
restRequest.execute(jsonCallback);
}
function jsonCallback(json) {
log("@jsonCallback");
var output = JSON.stringify(json);
log(output);
alert(output);
}
//----------------------------------------------------------------------------
// OAuth functions.
//----------------------------------------------------------------------------
function startOAuth() {
log("@startOAuth");
var authorizeButton = document.getElementById('authorize-button');
window.setTimeout(checkAuth, 1); // check auth in 1 ms
function checkAuth() {
log("@checkAuth");
gapi.auth.authorize({
client_id: m_clientId,
scope: m_scopes,
immediate: true
}, handleAuthResult);
}
function handleAuthResult(authResult) {
log("@handleAuthResult");
if (authResult && !authResult.error) {
log("@handleAuthResult - authResult=true");
log(authResult); // authResult is a token (with 3600 second expiration).
authorizeButton.disabled = true;
useAuthResults();
} else {
log("@handleAuthResult - authResult=false");
authorizeButton.disabled = false;
authorizeButton.onclick = handleAuthClick;
}
}
function handleAuthClick() {
log("@handleAuthClick");
gapi.auth.authorize({
client_id: m_clientId,
scope: m_scopes,
immediate: false
}, handleAuthResult);
return false;
}
function useAuthResults() {
log("@useAuthResults");
// Get the Google+ user's ID and name (member info).
gapi.client.load('plus', 'v1', function () {
log("@gapi.client.load callback");
var request = gapi.client.plus.people.get({ 'userId': 'me' });
request.execute(function (aInfo) {
log("@request.execute callback");
if (aInfo.code !== undefined) {
alert('Google+ API returned ' + aInfo.code + ': ' + aInfo.message);
} else {
// Here with successful sign-in. Display the user name.
log('Google+ user id, name: ' + aInfo.id + ', ' + aInfo.displayName);
authorizeButton.value = aInfo.displayName + " +" + aInfo.id;
}
});
});
}
}
}
function log(msg) {
if (console) console.log(msg);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=gapiIsReady" type="text/javascript"></script>
</head>
<body>
<h1>Test3a</h1>
<p>This pages demonstrates a problem I am having using gapi.client.request with gapi.auth.</p>
<input type="button" id="query-button" value="Query"><br>
<input type="button" id="startOAuth-button" value="Start OAuth"><br>
<input type="button" id="authorize-button" value="Authorize"><br>
<p>Steps...</p>
<p>1. Click "Query" to run a gapi.client.request Google Fusion Table SQL-get query returning
a count of rows. This will run successfully until OAuth is used in steps 2 and 3.</p>
<p>2. Click "Start OAuth" to run an immediate:true authorization against Google+. If you
are currently signed into Google+, your user name will be displayed in the third button.</p>
<p>3. If your Google+ user name is not displayed in the third button, press it ("Authorize")
and sign into Google+.</p>
<p>4. Click the "Query" button again.
The query will run without error when pressed within about 30 seconds of OAuth authorization.
After that, the query fails with a 403 error. WHY?</p>
</body>
</html>
Fusion Tables クエリを有効にするためではなく、ユーザーごとのページの使用状況を追跡するために Google+ サインインを使用するつもりであることに注意してください。
私はOAuthとgapi.client.requestを初めて使用するので、これは私の単純な誤解かもしれません。
洞察をありがとう。