【问题标题】:Google OAuth 2 access token not working as expected some hours after authorizing授权数小时后,Google OAuth 2 访问令牌未按预期工作
【发布时间】:2018-03-14 23:05:24
【问题描述】:

我正在使用 Google Identity Platform 的 OAuth 2.0 流程授权 javascript/HTML 教师观察表写入 Google 表格文档。大多数时候一切都运行良好;然而,昨晚我们的一位校长遇到了以下错误:

“请求具有无效的身份验证凭据。需要 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。请参阅 https://developers.google.com/identity/sign-in/web/devconsole-project。”

我确定他在下午启动了观察工具,现在大概五个小时后正在尝试点击提交按钮。我的预感是令牌已过期,但从 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();
}

谢谢!

【问题讨论】:

    标签: oauth oauth-2.0 google-oauth


    【解决方案1】:

    类似的问题是我从授权的 Javascript 起源引起的问题。 “在 Authorized JavaScript origins 字段中,输入您的应用程序的来源。您可以输入多个来源以允许您的应用程序在不同的协议、域或子域上运行。您不能使用通配符。在下面的示例中,第二个 URL 可以成为生产 URL。”取自https://developers.google.com/identity/sign-in/web/devconsole-project.If 提示查看任务来自电子邮件,必须验证电子邮件来源 - 或 - 设备用于多个帐户,令牌将不会保留。如果 api 使用不当,它将在短时间内允许功能,然后失败。

    【讨论】:

    • 我不认为这是我面临的问题 - 该工具位于静态生产 URL 中,并且始终从相同的 URL 工作。我现在发现访问令牌在一小时后过期,虽然 JS 库旨在自动刷新它,但如果计算机处于睡眠状态或离线状态,这可能不会正确发生。我现在正在查看stackoverflow.com/questions/32150845/…,作为在令牌过期时强制刷新的一种方式!
    【解决方案2】:

    这可能很有用,在 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; }
    

    【讨论】:

      【解决方案3】:

      我相信How to refresh expired google sign-in logins? 有我需要的答案。由于我的所有 API 调用同时发生,我在页面加载时添加了一个新 Date(),在提交流程开始时添加了第二个新 Date(),如果它们相隔超过 45 分钟(2,700,700 毫秒),我使用 gapi .auth2.getAuthInstance().currentUser.get().reloadAuthResponse() 以强制刷新访问令牌,如 https://developers.google.com/identity/sign-in/web/reference#googleuserreloadauthresponse 中所述。

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

      时间会证明这是否真的解决了问题,但我充满希望!

      【讨论】:

        【解决方案4】:

        我希望它可以帮助你朋友,错误是因为你有错误的时间,你去日期和时间设置然后按现在同步。

        【讨论】:

          猜你喜欢
          • 2014-08-10
          • 2015-02-24
          • 1970-01-01
          • 1970-01-01
          • 2014-03-19
          • 1970-01-01
          • 2021-05-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多