Google API PHP 离线访问,“invalid_grant:代码已被赎回”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32705682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google API PHP offline access, "invalid_grant: Code was already redeemed"
提问by unfulvio
How to authorize a Google Client permanently until the user revokes authorization?
如何在用户撤销授权之前永久授权 Google 客户端?
I am trying to make an app that connects to Google Calendar. It has to run in PHP and therefore I am using the Google API PHP client provided by google.
我正在尝试制作一个连接到 Google 日历的应用程序。它必须在 PHP 中运行,因此我使用的是 google 提供的 Google API PHP 客户端。
The app needs to have offline access so it works when the user is not in the session. The app is intended to let the user to manage and display his calendars publicly on websites and such.
该应用程序需要离线访问,以便在用户不在会话中时工作。该应用程序旨在让用户在网站等上公开管理和显示他的日历。
I have created credentials in Google Console, using service method (with a client ID and client secret). Using the Google API client I also requested authorization from the user. I open a new browser window, the user authorizes, an authorization code is returned by Google. I take this code, store it and use it to authorize the client, which successfully connects to Google Calendar and exchange data.
我使用服务方法(使用客户端 ID 和客户端密码)在 Google 控制台中创建了凭据。使用 Google API 客户端,我还请求用户授权。我打开一个新的浏览器窗口,用户授权,谷歌返回一个授权码。我将这段代码存储起来并使用它来授权客户端,该客户端成功连接到 Google 日历并交换数据。
Now, I understood this is a token that is going to expire. Unless one uses offline access, which I set. However, after a few minutes or less I will always get an error: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.
现在,我明白这是一个即将过期的令牌。除非有人使用我设置的离线访问。但是,几分钟或更短时间后,我总是会收到错误消息:Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.
This is the code I use to connect the client:
这是我用来连接客户端的代码:
$client = new \Google_Client();
$client->setApplicationName( 'My App' );
$client->setScopes( array( \Google_Service_Calendar::CALENDAR ) );
$client->setClientId( $this->google_client_id );
$client->setClientSecret( $this->google_client_secret );
$client->setRedirectUri( $this->google_client_redirect );
$client->setAccessType( 'offline' );
if ( $code = $this->google_client_auth ) {
try {
$client->authenticate( $code );
} catch( \Exception $e ) {
var_dump( $e );
}
}
return new \Google_Service_Calendar( $client );
This is a method inside a class.
这是一个类中的方法。
The client ID and the client secret are stored in the app settings.
客户端 ID 和客户端密钥存储在应用程序设置中。
I'm also storing the code returned by the user in a setting, but I think this is where I"m doing it wrong? I am putting the link to a Google OAuth window in a separate method (which also uses the same client id and secret and sets offline method as well). And to get the authorization is working. I can get to the calendars. It just doesn't last long...
我还将用户返回的代码存储在一个设置中,但我认为这是我做错的地方?我将指向 Google OAuth 窗口的链接放在一个单独的方法中(它也使用相同的客户端 ID和秘密并设置离线方法)。并且获得授权正在起作用。我可以进入日历。它只是不会持续很长时间......
回答by DaImTo
There are three types of codes or tokens Googles Authentcation server returns.
Google 身份验证服务器返回三种类型的代码或令牌。
- Authentication code
- Access token
- Refresh token.
- 验证码
- 访问令牌
- 刷新令牌。
Authentication code
验证码
When a user clicks on the Authentcation form and grants your application access. Google returns to you an Authentcation code. You should take this code and exchange it for an Access token and a refresh token. This code is only used once if you try and use it again you will get an error message.
当用户单击身份验证表单并授予您的应用程序访问权限时。Google 会返回给您一个身份验证代码。您应该使用此代码并将其交换为访问令牌和刷新令牌。此代码仅使用一次,如果您再次尝试使用它,您将收到一条错误消息。
invalid_grant: Code was already redeemed.
invalid_grant:代码已被兑换。
Access token
访问令牌
Access tokens are used to access the APIs this token should be sent along with every request you make. Access tokens are short lived they work for an hour and then they stop working
访问令牌用于访问 API,此令牌应与您发出的每个请求一起发送。访问令牌是短暂的,它们工作一个小时,然后停止工作
Refresh token
刷新令牌
Refresh tokens should be saved on your server some place. Once the access token expires you can use the refresh token to get a new access token.
刷新令牌应该保存在你的服务器上的某个地方。访问令牌过期后,您可以使用刷新令牌来获取新的访问令牌。
Your problem is that you are saving the authentication code which is of no use to you. You need to find the refresh token and save that.
您的问题是您正在保存对您无用的身份验证代码。您需要找到刷新令牌并保存它。