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

如何在用户撤销授权之前对 Google 客户端进行永久授权?

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

应用需要具有脱机访问权限,以便在用户不在会话中时工作。该应用程序旨在让用户在网站等网站上公开管理和显示其日历。

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

现在,我明白这是一个即将过期的令牌。除非有人使用我设置的离线访问。但是,几分钟或更短时间后,我总是会收到一个错误:获取OAuth2访问令牌时出错,消息:“invalid_grant:代码已被兑换。

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

$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

Google身份验证服务器返回的代码或令牌有三种类型。

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

验证码

当用户单击“身份验证”窗体并授予您的应用程序访问权限时。谷歌会向你返回一个身份验证代码。应获取此代码并将其交换为 Access 令牌和刷新令牌。如果您尝试再次使用此代码,则仅使用此代码一次,您将收到一条错误消息。

invalid_grant:代码已兑换。

访问令牌

访问令牌用于访问 API,此令牌应与你发出的每个请求一起发送。访问令牌的生存期很短,它们工作一个小时,然后停止工作

刷新令牌

刷新令牌应保存在服务器上的某个位置。访问令牌过期后,可以使用刷新令牌获取新的访问令牌。

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


答案 2

推荐