Google Javascript API 401带有Fusion Table的凭据无效

时间:2015-04-08 18:26:35

标签: javascript oauth google-fusion-tables http-status-code-401

401无效回复:从Google搜索回复来看,这似乎是一个相当普遍的问题,但不幸的是,这些都没有帮助我完全解决我的问题。

我有一个需要基于Google登录的网页,然后从融合表中选择数据。在登录过程中,我检查用户是否具有对融合表的适当访问权限,因此我知道登录已经有效,并且他们是允许编辑该表的有效用户(与特定人员共享)。我还检查收到的令牌是否有效。因此,对于每次成功登录,我都知道他们有权访问该表(已与他们共享)和一个有效令牌(他们已登录)。

由于这是一个JavaScript应用程序,因此没有刷新令牌,只有访问令牌(在线访问)。提示确实说离线访问,但我认为这只是谷歌默认的事情。 我没有设置APIKey ,它解决了一些用户(不幸的是不一样)的另一个401错误(来自this stack overflow question)。该请求在Google Oauth开发人员控制台中正常运行。

大多数用户可以正常访问它,但对于某些用户,当他们运行查询以从融合表中选择数据时,他们在发送GET请求时总是会收到401错误(显示为401)控制台中的(Unathorized)和401:返回的错误中的凭据无效)。我无法在我的机器上重现这个问题,但我不知道它为什么会发生以及接下来我能做什么。

远程访问用户计算机非常困难,我无法在其上安装软件(如Fiddler)来查看标题,因此控制台日志记录也是如此。

我附加了一个失败请求的用户控制台的图像。 GET请求在我的计算机上看起来与 正好 相同(工作正常)。您可以看到令牌有效,它们已登录等。

enter image description here

以下是相关代码的简化版本(删除了敏感信息),其中包含checkAuth,validateToken和handleAuthResult2等额外的调试代码:

var clientId = 'my_client_id.apps.googleusercontent.com';
var ftTableID = 'fusiontableidstring';
var scopes = 'https://www.googleapis.com/auth/fusiontables https://www.googleapis.com/auth/drive.metadata.readonly  https://www.googleapis.com/auth/userinfo.email';
var accessToken;  
var email;
var name;  
var params = {
    'clientid': clientId,
    'cookiepolicy': 'single_host_origin',
    'scope': scopes,
    'approvalprompt': 'force',
    'include_granted_scopes': true,
    'callback': handleAuthResult
    };
gapi.auth.signIn(params);

//debug code
function validateToken() {
    $.ajax({
        url: 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' + accessToken,
        data: null,
        success: function(response){
            console.log(response)
            if (response.audience == clientId) {
                console.log('Our token is valid....');
            } else {
                console.log(response.audience + ' not equal to ' + clientId);
            }
        },  
        error: function(error) {
            console.log(error)
            console.log('Our token is not valid....');
        },
        dataType: "jsonp" 
    });
}

function checkAuth() {
    console.log("checking authorization");
    gapi.auth.authorize(
        {'client_id': clientId, 'scope': scopes, 'immediate': true},
        handleAuthResult2);
}

function handleAuthResult2(authResult) {
    if (authResult) { //result
        console.log(authResult.status);
        console.log(authResult);

        if (authResult.error) {
            reset();
            gapi.auth.authorize(
                {'client_id': clientId, 'scope': scopes, 'immediate': false},
                handleAuthResult);
        } else {
        }
    }
}
//end debug code

// Handle the results of the OAuth 2.0 flow.
function handleAuthResult(authResult) {
    if (authResult) { //result
        if (authResult.error) {
            console.log(authResult.error);
            reset();
        } else {
            //successfully signed in, requests can be sent (will automatically contain access token)
            accessToken = authResult.access_token;
            validateToken(); //debug only
            //check who the user is
            gapi.client.load('plus','v1').then(function() {
                gapi.client.plus.people.get({
                    'userId': 'me'
                }).then(function(res) {
                    var profile = res.result;
                    email = profile.emails[0].value;
                    name = profile.displayName;
                    document.getElementById("signinconfirmation").innerHTML = "You are signed in as " + email + "(" + name + ")" ;
                 //check permissions
                    }).then(function() {
                        gapi.client.load('drive', 'v2').then(function() {
                            gapi.client.drive.permissions.getIdForEmail({
                                'email': email,
                            }).then(function(resp) {
                                var userid = resp.result.id;
                                gapi.client.drive.permissions.get({
                                    'fileId': ftTableID,
                                    'permissionId': userid
                                }).then(function(resp2) {
                                    if(resp2.status == 200) {
                                    document.getElementById("signinconfirmation").innerHTML = "You are signed in as " + email + "(" + name + ") with correct permissions." ;
                                    } else {
                                    document.getElementById("signinconfirmation").innerHTML = name + " at " + email + " does not have the appropriate permissions to edit this table.";
                                    } 
                                },
                                 function(reason) { //drive permissions failed
                                document.getElementById("signinconfirmation").innerHTML = name + " at " + email + " does not have the appropriate permissions to edit this table.";
                                });
                        });
                    });
                });
            });
        }
    }
}

// build the request to SELECT data from Fusion Table.
function selectData() {
        var sqlValue = document.getElementById("searchvalue").value;
        var matchCondition = "CONTAINS";
        if (sqlValue.length == 0) {
            alert('No value entered!')
        } else {
            //escape single quotes in sqlValue
            sqlValue = sqlValue.replace(/'/g, "\\'");
            var sql = "SELECT ROWID, COUNTRY FROM " + ftTableID + " WHERE COUNTRY " + matchCondition + " '" + sqlValue + "' ORDER BY ADMINNAME";  
            query(sql, 'select-data-output');
        };
}
// Send SQL query to Fusion Tables.
function query(query, element) {
    var lowerCaseQuery = query.toLowerCase();
    var path = '/fusiontables/v2/query';
    var callback = function(element) {
        //handle response depending on output element
        return function(resp) {
            if (resp.rows) {
                createTable(resp, element);
            } else {
                //no rows returned
                if (resp.error) {
                    var tableID = element;
                    clearTable(tableID);
                    var tableDiv = document.getElementById(tableParentDiv);
                    var tableElement = document.createElement('table');
                    tableElement.id = tableID;

                    if (resp.error.code) {
                        var errorText = "Error code: " + resp.error.code;
                        errorText += '\n' + resp.error.message;
                        tableElement.innerHTML = errorText;
                    } else {
                        tableElement.innerHTML = "An unknown error occurred " + resp.error;
                    }
                    tableDiv.appendChild(tableElement);
                    if (resp.error.code == 401) {
                        checkAuth(); //debug only
                    }

                } else {
                    alert("No results for that search. Check spelling and select from options.");
                     clearTable(element);
                } 
            }
        };
    }
    if (lowerCaseQuery.indexOf('select') != 0 &&
        lowerCaseQuery.indexOf('show') != 0 &&
        lowerCaseQuery.indexOf('describe') != 0) {
        // is update query
        var body = 'sql=' + encodeURIComponent(query);
        runClientRequest({
            path: path,
            body: body,
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              'Content-Length': body.length
            },
            method: 'POST'
        }, callback(element));
    } else {
        runClientRequest({
            path: path,
            params: { 'sql': query }
        }, callback(element));
    }
}

// Execute the client request.
function runClientRequest(request, callback) {
    var restRequest = gapi.client.request(request);
    console.log("the restRequest is: " + JSON.stringify(restRequest));
    restRequest.execute(callback);
}

1 个答案:

答案 0 :(得分:0)

对于后代:问题不是OAuth流程,用户没有设置正确的Google Apps域权限是一个问题。当组织为用户子域打开融合表服务时,错误就消失了。