Google API PHP离线访问,“invalid_grant:代码已被兑换”

时间:2015-09-21 22:44:42

标签: php oauth google-api google-oauth google-api-php-client

如果用户撤销授权,如何永久授权Google客户端?

我正在尝试创建一个连接到Google日历的应用。它必须在PHP中运行,因此我使用谷歌提供的Google API PHP客户端。

该应用需要具有离线访问功能,以便在用户不在会话中时才能运行。该应用程序旨在让用户在网站上公开管理和显示他的日历。

我使用服务方法(使用客户端ID和客户端密钥)在Google控制台中创建了凭据。使用Google API客户端,我还要求用户授权。我打开一个新的浏览器窗口,用户授权,Google会返回授权码。我使用此代码,存储并使用它来授权客户端,该客户端成功连接到Google日历并交换数据。

现在,我知道这是一个即将到期的令牌。除非我使用离线访问,我设置。但是,在几分钟或更短时间后,我将始终收到错误消息: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.

这是我用来连接客户端的代码:

$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和客户端密钥存储在应用程序设置中。

我也将用户返回的代码存储在一个设置中,但我认为这是我做错的地方?我将链接放到一个单独的方法中的Google OAuth窗口(也使用了相同的客户端ID和密码以及设置离线方法)。并且获得授权正在工作。我可以访问日历。它不会持续很长时间......

1 个答案:

答案 0 :(得分:28)

有三种类型的代码或令牌谷歌认证服务器返回。

  1. 验证码
  2. 访问令牌
  3. 刷新令牌。
  4. 验证码

    当用户点击“验证表”并授予您的应用程序访问权限时。 Google会向您返回一个Authentcation代码。您应该使用此代码并将其交换为Access令牌和刷新令牌。此代码仅在您尝试再次使用时使用一次,您将收到错误消息。

      

    invalid_grant:代码已被兑换。

    访问令牌

    访问令牌用于访问API,此令牌应与您发出的每个请求一起发送。访问令牌是短暂的,他们工作了一个小时,然后他们停止工作

    刷新令牌

    刷新令牌应该保存在服务器的某个地方。访问令牌到期后,您可以使用刷新令牌获取新的访问令牌。

    您的问题是您正在保存对您没用的验证码。您需要找到刷新令牌并保存。