OAuth2.0 令牌奇怪行为(Invalid Credentials 401)

Posted

技术标签:

【中文标题】OAuth2.0 令牌奇怪行为(Invalid Credentials 401)【英文标题】:OAuth2.0 token strange behaviour (Invalid Credentials 401) 【发布时间】:2013-07-22 17:24:35 【问题描述】:

通常,Google OAuth2.0 机制运行良好。

    用户确认访问具有选定范围的 Google 帐户的权限。 刷新令牌被检索并保存到长时间存储中。 每次需要(如果访问令牌过期)访问令牌都会被检索并用于访问 API。

但有时(迄今为止只有两次超过 6 个月)我遇到了奇怪的行为:

对 Google API 的请求会返回 Invalid Credentials (401) 错误。 刷新访问令牌(使用存储的刷新令牌)没有帮助。

这是我在测试这个问题时得到的一些结构化输出:

+ -------------------------------------------------- ------------------------------------ + | 1.尝试刷新令牌。 | | 2.完成刷新令牌。 | + -------------------------------------------------- ------------------------------------ + |使用权: ************************************************ **** | |刷新:********************************************* | |过期:3600 | |创建时间:2013-07-23 13:12:36 | + -------------------------------------------------- ------------------------------------ +

我还尝试通过发送请求来验证“新鲜”访问令牌 https://www.googleapis.com/oauth2/v1/tokeninfo

+ -------------------------------------------------- ------------------------------------ + | 1. 尝试检查令牌。 | | 2.完成检查令牌令牌。 | + -------------------------------------------------- ------------------------------------ + |发给:************.apps.googleusercontent.com | |观众:************.apps.googleusercontent.com | |用户 ID:************ | | expires_in: 3600 | |电子邮件:**********@gmail.com | |验证电子邮件:1 | | access_type: 离线 | |范围:: | + -------------------------------------------------- ------------------------------------ + | https://www.googleapis.com/auth/userinfo.email | | https://www.googleapis.com/auth/userinfo.profile | | https://www.googleapis.com/auth/plus.me | | https://www.googleapis.com/auth/drive | + -------------------------------------------------- ------------------------------------ +

但是当我尝试访问驱动器提要时,响应是:

调用 GET https://www.googleapis.com/drive/v2/files 时出错 (401) 凭据无效 领域:全球 原因:authError 消息:无效的凭据 位置类型:标题 地点:授权

我们在日历方面也遇到了同样的问题。 所以:

    令牌之前有效(一切正常)。 刷新令牌仍然有效。 请求提要时出现“无效凭据”错误。 所有其他令牌仍然可以正常工作,这意味着代码有效。

通常当令牌被撤销时,尝试刷新令牌时会返回“invalid_grant”错误。

问题

    此行为的原因可能是什么?如果刷新令牌被撤销或以其他方式无效,新访问令牌的请求是否会产生错误? 有没有办法验证刷新令牌?

【问题讨论】:

在多次后续请求后,我遇到了同样奇怪的行为。 【参考方案1】:

根据有关错误和错误代码的 Google API 文档:

https://developers.google.com/drive/handle-errors#401_invalid_credentials

401: Invalid Credentials

Invalid authorization header. The access token you're using is either expired or invalid.

error: 
  errors: [
   
  "domain": "global",
  "reason": "authError",
  "message": "Invalid Credentials",
  "locationType": "header",
  "location": "Authorization",
  
  ],
  "code": 401,
  "message": "Invalid Credentials"
  

这与您的错误版本完全匹配,因此很可能 Google 认为您的请求有问题。

但是,众所周知,Google API 请求可能会返回明显无助于实际诊断问题的错误。由于多种原因,我收到了“无效凭据”错误。这几乎总是真的,因为我做了一些我认为无关紧要的改变,但确实如此。

我的第一个想法(这里是在黑暗中拍摄)是转到 Google API 控制台:

https://code.google.com/apis/console

Google 的身份验证令牌验证器 (https://www.googleapis.com/oauth2/v1/tokeninfo) 可以返回有效响应,但可能会更改客户端密码或客户端 ID。

即使响应正文中的微小变化也可能导致此错误。

我不知道您是如何发出请求的,无论是通过 REST 调用还是客户端库,但我使用允许命令行界面进行 API 调用的 ruby​​ 库。我发现这个和 OAuth2 Playground 对诊断 Google API 调用非常有帮助。

仅供参考:我从 Google API 中只收到 2 个错误:“凭据无效”和“权限不足”。后者几乎总是与不良范围有关。前者就是其他一切。

我还要说,如果你在 6 个月内只经历了 2 次错误,那你是幸运的!

【讨论】:

感谢您的回复。错误匹配,问题是 refresh_token 仍然允许获取新的 access_tokens,这也可以验证。我对其他用户也有同样的错误(401 Invalid Credentials),但不同的是,当请求新的 access_token 时,invalid_grant 错误是发布。因此很容易说令牌已过期或被撤销。 当我尝试通过 google Plus 登录时,我得到了一个 access_token,但是当我使用该 access_token 时,我去获取用户信息它给了我 401 错误。如果我的凭据错误,那么我如何获得访问令牌?如果我有访问令牌,那为什么它不给我任何结果?请帮忙:(【参考方案2】:

我最近遇到了这个奇怪的错误。我的解决方法:我在重定向到 AuthUrl 之前放置了取消设置所有会话的功能。

【讨论】:

【参考方案3】:

当我尝试在 google 控制台中更改重定向 url,然后在服务器上更新我的 json 凭据文件时,我遇到了这个问题。在重新开始之前,我必须清除会话变量。因此,在您的项目中只需执行一次:

session_start(); //starts a session
session_unset(); //flushes out all the contents previously set

记住在空运行一次后删除session_unset()

【讨论】:

【参考方案4】:

我在开发环境中。我也有这个问题。

首先我尝试刷新凭据。没有结果。然后我删除了我的应用程序(因为我仍在开发环境中,这没关系,但如果您已经在生产环境中使用此操作,请注意此操作),创建一个新应用程序,更新客户端上的凭据 JSON.. . 仍然没有结果。

我通过打开一个未登录我的 Google 帐户的新浏览器实例解决了这个问题(私人浏览,因为我使用的是 Firefox),再次登录我的 Google 帐户,并尝试使用我的客户端(即Web 应用程序)。我按预期被重定向到授权屏幕,之后,它对我来说很好。

【讨论】:

如果是账户相关的问题,为什么换浏览器时会起作用? (现在我也发生了同样的事情) @gedamial 在我的情况下并检查其他人的回复,我不知道这是否是与帐户相关的问题,因为它在更改会话后起作用。这对我有用,但我不太清楚到底出了什么问题。【参考方案5】:

当我移除对特定应用的 Google 帐户的访问权限时,我收到了(401) Invalid Credentials。所以我要做的就是再次请求授权 URL(以https://accounts.google.com/o/oauth2/auth 开头的那个)。

【讨论】:

【参考方案6】:

当我需要将范围从只读更改为读写所有文件时,我遇到了同样的问题。因此,我将文件顶部的范围从只读更新为:

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/drive'];

Google,在他们的 API 指南中,有这些 cmets 说,每当您更改范围时,您必须更新凭据。我相信这意味着,尽管我不确定,令牌必须更新。旧令牌仍由 Google 持有,它认为我只有只读访问权限,因此它会返回 401 错误。所以,我需要重新制作我的令牌,但谷歌从未提供一个新的同意屏幕,允许我说允许读取和写入所有文件。所以,我需要让那个屏幕再次出现,所以它会创建一个新的令牌来替换旧的:

fs.readFile(TOKEN_PATH, function(err, token) 
    if (err) 
      getNewToken(oauth2Client, callback);
     else 
        getNewToken(oauth2Client, callback);
    //   oauth2Client.credentials = JSON.parse(token);
    //   callback(oauth2Client);
    
  );

因为我已经保存了一个令牌,所以它永远不会创建一个新的。所以,我只是注释掉了旧令牌的使用,并告诉它得到一个新的令牌,不管我们有没有。然后,我去了我在 Google 中的连接应用程序并删除了我的旧连接凭据。我不确定这一步是否必要,但我只是想访问我的个人帐户。然后,当我运行我的程序时,它提示我重新进行身份验证,一切正常,我没有收到身份验证错误。完成后,请确保删除注释掉的行以使用已制作的令牌。我正在使用 Google API quickstart.js 文件来完成所有这些工作。

因此,当我更新我的范围时,旧令牌仍在使用只读范围,因此我会得到 (401) Invalid Credentials。

【讨论】:

【参考方案7】:

当我删除 c:\Users\[user]\.credentials 中的文件 json 时,我解决了这个问题。

【讨论】:

【参考方案8】:

在谷歌浏览器中清除存储对我有用(不知道“清除存储”正在清除的所有细节):

    F12 (Ctrl+Shift+I) Application标签 Clear storage

【讨论】:

【参考方案9】:

这种行为可能是由于 Google describes 的限制如下:

目前每个客户端每个用户帐户的刷新令牌限制为 50 个。如果达到限制,创建新令牌会自动使最旧的令牌无效,而不会发出警告。此限制不适用于服务帐号。

用户帐户或服务帐户可以在所有客户端上拥有的令牌总数也有更大的限制。大多数普通用户不会超过此限制但开发者的测试帐户可能

【讨论】:

【参考方案10】:

这个错误我也有同样的问题:

The redirect URI in the request, does not match the ones authorized for the OAuth client.

但是 abhishek77in 在这里找到了这个非常简单的解决方案:

https://coderwall.com/p/fmr5ag/avoid-invalid-credentials-with-google-oauth2

解决办法是:

如果您正在使用 https://github.com/zquestz/omniauth-google-oauth2 确保 按照 README 中的说明进行操作。 "您必须启用 "Contacts API" 并且 通过 Google API 控制台“Google+ API”。

在 Google API 控制台中启用这些为我解决了“无效凭据”问题。

【讨论】:

【参考方案11】:

userInfo: Invalid Credentials 我收到以下错误,因为我试图访问的范围数组元素,即我从 google+ api 范围页面获得的链接的个人资料和电子邮件:变得有点错误/无效所以我去了我的同意屏幕并在那里 在 Scopes for Google APIs 下提到了 email profile openID 悬停在每个我到达那里的相应 url 用这些替换我的旧 URL 解决了我的错误

【讨论】:

【参考方案12】:

也许这对某人有帮助:

我在使用日历 API 的 javascript Google-API 客户端时遇到了类似的问题。在随机时间它会起作用,但大多数时候我得到了同样的错误。添加范围,测试密钥,没有任何帮助。几个小时后,我找到了这个解决方案,不知道它为什么起作用,但它为我解决了这个问题:

gapi.client.init(
    'apiKey': API_KEY,  <-- DOESN'T WORK
    'clientId': CLIENT_ID,
    'discoveryDocs': DISCOVERY_URLS,
    'scope': SCOPE
).then(function() 
    // gapi.client.setApiKey(API_KEY); <-- ADD THIS
)

【讨论】:

【参考方案13】:

如果您使用的帐户是 GSuite 设置的一部分,则可能需要将 GSuite Basic 添加到该帐户。你可以通过用户>点击用户>许可证。

【讨论】:

以上是关于OAuth2.0 令牌奇怪行为(Invalid Credentials 401)的主要内容,如果未能解决你的问题,请参考以下文章

PHP:Google plus Oauth 2.0 - 获取OAuth2访问令牌时出错,消息:'invalid_client'

Spring Security + Google OAuth2 登录:访问令牌为空?

OAuth2.0流程

OAUTH2.0 不记名令牌不工作

oAuth2.0:为啥需要“授权码”,然后才需要令牌?

Oauth2.0介绍