且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-16 15:52:14

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

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

401:无效的凭据无效的授权标头.您使用的访问令牌已过期或无效.错误: {错误:[{"域": "全局","原因": "authError","message": "无效的凭据","locationType": "标题","location": "授权",}],代码":401,"message": "无效的凭据"}}

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

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

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

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

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

即使响应正文中的微小变化也会导致此错误.

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

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

我还要说,如果你在 6 个月内只经历过 2 个错误,那你很幸运!

Usually, Google OAuth2.0 mechanism is working great.

  1. The user confirms permission to access Google account with selected scopes.
  2. The refresh token is retrieved and saved to long time storage.
  3. Each time needed (if the access token expired) access token is retrieved and used to access APIs.

But sometimes (thus far only two times for more than 6 months) I've experienced strange behaviour:

Requests to Google APIs return Invalid Credentials (401) error. Refreshing the access token (using the stored refresh token) does not help.

Here is some structured output I've got when testing this issue:

    + ------------------------------------------------------------------------- + 
    | 1.TRYING TO REFRESH THE TOKEN.                                            |
    | 2.DONE REFRESHING THE TOKEN.                                              |
    + ------------------------------------------------------------------------- + 
    |    access:           **************************************************** | 
    |   refresh:                  ********************************************* | 
    |   expires:                                                           3600 | 
    |   created:                                            2013-07-23 13:12:36 | 
    + ------------------------------------------------------------------------- + 

I've also tried to verify the "fresh" access token by sending requests to https://www.googleapis.com/oauth2/v1/tokeninfo

    + ------------------------------------------------------------------------- + 
    | 1. TRYING TO CHECK THE TOKEN .                                            |
    | 2. DONE CHECKING THE TOKEN THE TOKEN.                                     |
    + ------------------------------------------------------------------------- + 
    |       issued_to:                  ************.apps.googleusercontent.com |
    |        audience:                  ************.apps.googleusercontent.com |
    |         user_id:                                             ************ |
    |      expires_in:                                                     3600 |
    |           email:                                     **********@gmail.com |
    |  verified_email:                                                        1 |
    |     access_type:                                                  offline |
    |         scopes::                                                          |
    + ------------------------------------------------------------------------- + 
    | 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                                     |
    + ------------------------------------------------------------------------- + 

But when I try to access drive feed the response is:

    Error calling GET https://www.googleapis.com/drive/v2/files (401) Invalid Credentials

    domain:         global
    reason:         authError
    message:        Invalid Credentials
    locationType:   header
    location:       Authorization

We also experienced the same issue with calendars. So:

  1. Token was valid before (everything worked).
  2. Refreshing token still works.
  3. Requesting a feed responds with "Invalid Credentials" error.
  4. All the other tokens are still working great, meaning that the code is valid.

Normally when the token is revoked "invalid_grant" error is returned when trying to refresh the token.

Questions

  1. What can be the reason for this behaviour? If the refresh token was revoked or got invalid in some other way, should the request for new access token produce error?
  2. Is there a way to validate the refresh token?

Per the Google API docs on errors & error codes:

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"
  }
}

This matches your version of the error exactly, and so is very probably what Google thinks is wrong with your request.

But, as you well know, Google API requests can return errors that are distinctly unhelpful to actually diagnosing the problem. I have gotten "Invalid Credentials" errors for a number of reasons. It is almost always really because I have made some sort of change that I thought would not matter, but really does.

My first thought (shot in the dark here) would be to go to the Google API console:

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

Googles auth token verifier ( https://www.googleapis.com/oauth2/v1/tokeninfo ) can return a valid response, but maybe the client secret or client id will have been changed.

Even tiny changes in the response body can also cause this error.

I don't know how you are making requests, whether by REST calls or a client lib, but I use the ruby lib which allows a command line interface to making API calls. I have found this & the OAuth2 Playground very helpful in diagnosing Google API calls.

Just an FYI: I have only gotten 2 errors from the Google API: "Invalid Credentials" and "Insufficient Permissions". The latter has almost always had to do with bad scopes. The former is just about everything else.

I would also say that if you have only experienced 2 errors in 6 months, you are lucky!