我有一个管理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;
}
我显然没有正确刷新令牌或其他东西,但我无法理解。
任何帮助表示感谢。
答案 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' );
请注意:我不是说"这是应该的方式"但我希望它可以给你一个想法。希望它有所帮助!