谷歌API PHP离线访问,“invalid_grant:代码已经兑换"
如何在用户撤销授权之前永久授权 Google 客户?
我正在尝试制作一个连接到 Google 日历的应用.它必须在 PHP 中运行,因此我使用的是 google 提供的 Google API PHP 客户端.
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.
应用需要离线访问才能在用户不在会话中时正常工作.该应用旨在让用户在网站等上公开管理和显示他的日历.
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.
我使用服务方法(使用客户端 ID 和客户端密码)在 Google 控制台中创建了凭据.使用 Google API 客户端,我还请求用户授权.我打开一个新的浏览器窗口,用户授权,谷歌返回一个授权码.我将这段代码存储起来并使用它来授权客户端,从而成功连接到 Google 日历并交换数据.
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.
现在,我明白这是一个即将过期的令牌.除非使用我设置的离线访问.但是,几分钟或更短的时间后,我总是会收到错误消息:Error fetching OAuth2 access token, message: 'invalid_grant: Code was alreadyempted.
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.
这是我用来连接客户端的代码:
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 );
这是一个类中的方法.
客户端 ID 和客户端密钥存储在应用设置中.
The client ID and the client secret are stored in the app settings.
我还将用户返回的代码存储在设置中,但我认为这是我做错的地方?我将指向 Google OAuth 窗口的链接放在单独的方法中(该方法也使用相同的客户端 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 的身份验证服务器返回三种类型的代码或令牌.
There are three types of codes or tokens Googles Authentcation server returns.
- 验证码
- 访问令牌
- 刷新令牌.
验证码
当用户点击身份验证表单并授予您的应用程序访问权限时.Google 会返回给您一个身份验证代码.您应该使用此代码并将其交换为访问令牌和刷新令牌.此代码仅使用一次,如果您再次尝试使用它,您将收到一条错误消息.
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.
invalid_grant:代码已被兑换.
invalid_grant: Code was already redeemed.
访问令牌
访问令牌用于访问 API,此令牌应与您发出的每个请求一起发送.访问令牌是短暂的,它们工作一个小时,然后停止工作
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
刷新令牌
刷新令牌应该保存在你的服务器上的某个地方.访问令牌过期后,您可以使用刷新令牌获取新的访问令牌.
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.
相关文章