Analytics API 返回:错误请求 - invalid_grant

2021-12-29 00:00:00 curl php google-analytics

我使用的是 Google Analytics API v3.我现在解释一下我的申请流程

I'm using the Google Analytics API v3. I'll explain the flow of my application now

我在这里使用了这个文档:https://developers.google.com/accounts/docs/OAuth2WebServer

I used this documentation here: https://developers.google.com/accounts/docs/OAuth2WebServer

首先,为用户生成一个 OAUTH-URL.网址是这样的

First, an OAUTH-URL is generated for the user. The URL looks like this

https://accounts.google.com/o/oauth2/auth?
client_id={CLIENT-ID}&
redirect_uri={REDIRECT-URL}&
state={CUSTOM-NUMBER}&
response_type=code&
access_type=offline&
approval_prompt=force&
scope=https://www.googleapis.com/auth/analytics

当用户点击链接时,他进行了身份验证.之后,通过代码,我获得了访问和刷新令牌.

When the user clicks on the link he authenticates. Afterwards, with the code, I'm getting the access and refresh token.

我正在向 https://www.googleapis.com/oauth2/v3/token 发送带有参数的请求

I'm sending a request to https://www.googleapis.com/oauth2/v3/token with the parameters

code = Code from Analytics
grant_type = authorization_code
client_secret = CLIENT_SECRET
client_id = CLIENT_ID
redirect_uri = REDIRECT_URI

我发送的 cURL 选项如下:

The cURL options I send are the following:

CURLOPT_HTTPHEADER = array('Content-Type: application/x-www-form-urlencoded')

当然,帖子数据是使用 http_build_query 构建的,因此我可以使用该内容类型标头.

And of course, the post data is built with http_build_query so I can use that content-type header.

然后,我使用此 URL 获取用户的所有个人资料

Then, I am getting all profiles of the user, with this URL

https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles

这有效,我列出了所有配置文件.然后用户选择其中一个配置文件,我的库获取用户的当前数据(浏览量、访问量等)

This works, and I'm listing all the profiles. The user then selects one of the profiles, and my library gets the current data for the user (pageviews, visits, etc.)

我现在遇到的问题是,当我想每天使用 cron 刷新数据时,我收到错误消息:

The problem I'm having now, is, that, when I want to refresh the data everyday with a cron, I'm getting the error message:

'error' => 'invalid_grant',
'error_description' => 'Bad Request'

但我不知道,为什么?

我在我的数据库中保存了配置文件的访问令牌和刷新令牌.然后,在我请求访问数据之前重新访问数据时,我会检查令牌是否有效.但即使这样也失败了.

I saved the access token and the refresh token for the profiles in my database. Then, when reaccessing data before I make requests to access data, I check if the token is valid. But even this fails.

我在这里做这个请求

https://accounts.google.com/o/oauth2/tokeninfo?access_token=ya29.BwHqH8NOPVhafk3SnwbqjLZMXub4Q8bemC-8vKVwp-UjRqaIHRXrzEV3WjInhGzl1-phIn7XI4NnDA

它告诉我,访问令牌无效(这很神秘,因为我刚刚通过身份验证,5 秒后令牌不再有效?

It tells me, that the access token is invalid (Which is mysterious, since I just authenticated and 5 seconds later the token isn't valid anymore?

无论如何,然后我尝试用这个请求刷新它

Anyway, then I try to refresh it with this request

URL: https://www.googleapis.com/oauth2/v3/token
Parameters: 

client_secret = CLIENT_SECRET
client_id = CLIENT_ID
refresh_token = REFRESH_TOKEN From my database
grant_type = refresh_token

cURL Options: CURLOPT_HTTPHEADER = array('Content-Type: application/x-www-form-urlencoded')

然后,带有使用 http_build_query 构建的参数的 post 请求

Then, a post request with the params built with http_build_query

响应如下

string(67) "{ "error": "invalid_grant", "error_description": "Bad Request" } "

但我不知道为什么.我正在使用 5 分钟前获得的访问令牌和刷新令牌,以及适用于第一个请求的令牌.为什么 5 分钟后使用相同的令牌不起作用?为什么我什至不能刷新令牌?

But I have no idea why. I'm using the access token and refresh token I got 5 minutes earlier and the ones which worked for the first request. Why doesn't it work 5 minutes later with the same tokens? And why can't I even refresh the token?

推荐答案

无效授权通常有两个可能的原因.

Invalid grant normally has two possible causes.

  1. 您服务器的时钟与 NTP 不同步.(解决方案:检查服务器时间,如果不正确修复它.)
  2. 已超出刷新令牌限制.(解决方案:您无能为力,他们不能使用更多刷新令牌)应用程序可以请求多个刷新令牌.例如,这在用户想要在多台机器上安装应用程序的情况下很有用.在这种情况下,需要两个刷新令牌,每个安装一个.当刷新令牌的数量超过限制时,旧令牌将失效.如果应用程序尝试使用无效的刷新令牌,则会返回 invalid_grant 错误响应.每对唯一的 OAuth 2.0 客户端的限制为 25 个刷新令牌(请注意,此限制可能会发生变化).如果应用程序继续为同一个 Client/Account 对请求刷新令牌,一旦发出第 26 个令牌,先前发出的第一个刷新令牌将失效.第 27 个请求的刷新令牌将使之前颁发的第 2 个令牌无效,依此类推.

您应该只存储刷新令牌.访问令牌将在一小时后过期.下面是对不同调用 Google 3 legged Oauth2 flow 的介绍.

You should only be storing the Refresh token. The Access token will expire after an hour. Here is a walk though on the different calls Google 3 legged Oauth2 flow.

我无法从您的代码中找出任何内容,这看起来有点令人困惑.但我看不出任何看起来有问题的地方,这就是为什么我猜测这可能是前两个问题之一.

I wasn't able to figure out anything from your code it looked a little confusing. But I couldn't see anything that really looked wrong that's why I am guessing it might be one of the first two issues.

相关文章