授权后数小时,Google OAuth 2访问令牌未按预期工作

授权后数小时,Google OAuth 2访问令牌未按预期工作,oauth,oauth-2.0,google-oauth,Oauth,Oauth 2.0,Google Oauth,我正在使用GoogleIdentity平台的OAuth2.0流来授权javascript/HTML教师观察表单写入GoogleSheets文档。大多数时候,一切都运转良好;然而,昨晚我们的一位负责人犯了以下错误: 请求具有无效的身份验证凭据。应为OAuth 2访问令牌、登录cookie或其他有效的身份验证凭据。请参阅 我确定他是在下午启动了这个观察工具,现在大概五个小时后,他正试图点击提交按钮。我的预感是令牌已经过期,但从Google的文档来看,JS auth库似乎是为了在必要时处理刷新访问令牌

我正在使用GoogleIdentity平台的OAuth2.0流来授权javascript/HTML教师观察表单写入GoogleSheets文档。大多数时候,一切都运转良好;然而,昨晚我们的一位负责人犯了以下错误:

请求具有无效的身份验证凭据。应为OAuth 2访问令牌、登录cookie或其他有效的身份验证凭据。请参阅

我确定他是在下午启动了这个观察工具,现在大概五个小时后,他正试图点击提交按钮。我的预感是令牌已经过期,但从Google的文档来看,JS auth库似乎是为了在必要时处理刷新访问令牌-我相信实际上不可能手动获取刷新令牌

我使用的基本上是示例身份验证代码,应用程序会相应地响应注销。也就是说,如果我在另一个选项卡中注销,则“提交”按钮将被禁用,并且“登录”按钮将再次出现。假设令牌过期是这里的问题,那么关于如何正确识别令牌是否已过期以及如何请求新令牌(理想情况下无需用户交互)有何想法?或者,如果不是过期问题,那还能是什么?该用户已成功提交早期观察中的数据;就在这一次,他在这段时间里等待了约5个小时(可能会失去互联网连接/睡在笔记本电脑上)

以下是身份验证代码:

var clientId = ""; //id removed
var discoveryDocs = ["https://sheets.googleapis.com/$discovery/rest?version=v4"];
var scopes = "https://www.googleapis.com/auth/spreadsheets";
var authorizeButton = document.getElementById('authorize-button');
function handleClientLoad() {
    gapi.load('client:auth2', initClient);
}
function initClient() {
    gapi.client.init({
        discoveryDocs: discoveryDocs,
        clientId: clientId,
        scope: scopes
    }).then(function () {
        gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
        updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
        authorizeButton.onclick = handleAuthClick;
    });
}
function updateSigninStatus(isSignedIn) {
    if (isSignedIn) {
        authorizeButton.style.display = 'none';
        document.getElementById('submit').disabled = false;
        findRow(); //find the empty row once we're logged in
    } else {
        authorizeButton.style.display = 'block';
        document.getElementById('submit').disabled = true;
    }
}
function handleAuthClick(event) {
    gapi.auth2.getAuthInstance().signIn();
}

谢谢大家!

类似于我在授权Javascript源代码中导致的问题。
“在授权的JavaScript源字段中,输入应用程序的源。您可以输入多个源,以允许应用程序在不同的协议、域或子域上运行。您不能使用通配符。在下面的示例中,第二个URL可以是生产URL。”取自“提示查看”任务的电子邮件,必须验证电子邮件来源-或者-设备用于多个帐户,令牌将不会保留。如果api使用不当,它将允许短时间的功能,然后失败。

类似于我在授权Javascript源代码中导致的问题。
“在授权的JavaScript源字段中,输入应用程序的源。您可以输入多个源,以允许应用程序在不同的协议、域或子域上运行。您不能使用通配符。在下面的示例中,第二个URL可以是生产URL。”取自“提示查看”任务的电子邮件,必须验证电子邮件来源-或者-设备用于多个帐户,令牌将不会保留。如果api使用不当,它将允许短时间的功能,然后失败。

这可能很有用,在authflow中,选项中没有作用域或id

   /** * Initiate auth flow in response to user clicking authorize button. * * 
   @param {Event} event Button click event. */ function 
   handleAuthClick(event) { 
   gapi.auth.authorize( {client_id: '[@app:client_id]', scope: 
   ["googleapis.com/auth/calendar"], immediate: false}, handleAuthResult); 
   return false; }

这可能很有用,因为在authflow中,选项中没有作用域或id

   /** * Initiate auth flow in response to user clicking authorize button. * * 
   @param {Event} event Button click event. */ function 
   handleAuthClick(event) { 
   gapi.auth.authorize( {client_id: '[@app:client_id]', scope: 
   ["googleapis.com/auth/calendar"], immediate: false}, handleAuthResult); 
   return false; }
我相信你已经找到了我需要的答案。由于所有API调用同时发生,因此我在页面加载时添加了一个新日期(),在提交流开始时添加了第二个新日期(),如果它们之间的间隔超过45分钟(2700700ms),我将使用gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse()强制刷新访问令牌,如中所述

希望Google最终会更新他们的文档,以反映在使用auth2流和旧的auth流时这一必要步骤

时间会告诉我们这是否真的解决了问题,但我充满希望

我相信我已经找到了我需要的答案。由于所有API调用同时发生,因此我在页面加载时添加了一个新日期(),在提交流开始时添加了第二个新日期(),如果它们之间的间隔超过45分钟(2700700ms),我将使用gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse()强制刷新访问令牌,如中所述

希望Google最终会更新他们的文档,以反映在使用auth2流和旧的auth流时这一必要步骤


时间会告诉我们这是否真的解决了问题,但我充满希望

我希望它能帮助您的朋友,错误是因为您的时间不对,请转到“日期和时间设置”,然后立即按“同步”。我希望它能帮助您的朋友,错误是因为您的时间不对,进入“日期和时间设置”,然后按“立即同步”。

我不认为这是我面临的问题-该工具位于一个静态的生产URL,并且从同一URL始终如一地工作。现在我发现访问令牌在一个小时后过期,虽然JS库打算自动刷新它,但如果计算机处于睡眠或脱机状态,这可能不会正确发生。我现在把它看作是一种在令牌过期时强制刷新的方法!我不认为这是我面临的问题-该工具位于一个静态的生产URL,并且它从相同的URL一致地工作。现在我发现访问令牌在一个小时后过期,虽然JS库打算自动刷新它,但如果计算机处于睡眠或脱机状态,这可能不会正确发生。我现在把它看作是一种在令牌过期时强制刷新的方法!