invalid_grant代码已被兑换

时间:2017-07-04 23:48:09

标签: google-calendar-api google-api-php-client google-authentication

我有一个管理Google日历条目的PHP应用程序。它安装在我的两个站点上。

在第一个网站上,它已经运行了大约一年,没有问题,并且保持同步。

在另一个网站上(不同的Google帐户),我一直看到错误...

Invalid token formatarray (
  'error' => 'invalid_grant',
  'error_description' => 'Code was already redeemed.',
)

一直试图解决这个问题已经好几个星期了。以下是我的代码的一些片段(在WordPress中使用)...

$this->auth  = get_option( 'google_calendar_auth_code' ); // API Setting
$this->token = get_transient( 'google_calendar_token' );

$this->client = new Google_Client();
$this->client->setApprovalPrompt( 'force' );
$this->client->setAccessType( 'offline' );
$this->client->setApplicationName( 'MY_APP' );
$this->client->setClientId( '*****.apps.googleusercontent.com' );
$this->client->setClientSecret( '******' );
$this->client->setRedirectUri( 'urn:ietf:wg:oauth:2.0:oob' );
$this->client->setScopes( array( 'https://www.googleapis.com/auth/calendar.readonly', 'https://www.googleapis.com/auth/calendar.readonly' ) );

try {
    $this->calendar = new Google_Service_Calendar( $this->client );
} catch( Google_Service_Exception $e )  {
    error_log( 'ERROR: ' . $e->getMessage() );
}

if ( ! empty( $this->token ) )  {

    $this->client->setAccessToken( $this->token );

} else  {

try {

    $access_token = $this->client->authenticate( $this->auth );

} catch( Exception $e ) {

    error_log( 'Unable to connect to calendar. ' . $e->getMessage() );

    return false;

}

if ( $access_token )    {

    try {
        $this->client->setAccessToken( $access_token );
    } catch( Exception $e ) {
        error_log( 'Access token error. ' . $e->getMessage() . var_export( $access_token, true ) );
        return false;
    }

    set_transient( 'google_calendar_token', $access_token, 0 );

    $redirect = admin_url( 'edit.php' );

    wp_safe_redirect( $redirect );
    exit;

    } else  {
        return false;
    }

    $this->token = json_decode( $this->client->getAccessToken() );

    if ( ! defined( 'GOOGLE_TOKEN' ) )  {
        define( 'GOOGLE_TOKEN', true );
    }

    return true;

}

我显然没有正确刷新令牌或其他东西,但我无法理解。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:0)

您面临的问题是您正在尝试使用已使用的访问代码(如邮件描述的方式)。当您请求授权时,您将获得一个访问代码,类似于 4 / UpUXsWcYumk8bdK7GtMm81WeeWpuPvhwsOrgbWU 。这只能用于获取刷新令牌和访问令牌一次。之后,每次访问令牌到期时,您只使用刷新令牌来获取新的访问令牌。您需要做的是再次通过授权流程以获取新的访问代码,从而获得新的刷新令牌和访问令牌。

我建议你玩OAUth 2.0 Playground right here

虽然,基于您的代码。我认为你的问题在这里:

try {

$access_token = $this->client->authenticate( $this->auth );

}

您会看到,当您进行身份验证时,您必须提供身份验证网址返回的访问代码。由于该部分已完成,您不必再次对用户进行身份验证,而只需刷新访问令牌即可。所以你的流程应该是这样的:

if ( ! empty( $this->token ) )  {

    $this->client->setAccessToken( $this->token );

} else  {

    this->client->refreshToken(this->refreshToken); 
    this->client->setAccessToken(this->client->getAccessToken());

}

您可以使用$this->auth = get_option( 'google_calendar_auth_code' );

,而不是使用$this->refreshToken= get_option( 'google_refresh_token' );

请注意:我不是说"这是应该的方式"但我希望它可以给你一个想法。希望它有所帮助!