无法在 PHP 中刷新 OAuth2 令牌,授权无效
Posted
技术标签:
【中文标题】无法在 PHP 中刷新 OAuth2 令牌,授权无效【英文标题】:Unable to refresh OAuth2 token in PHP, invalid grant 【发布时间】:2013-11-19 19:26:58 【问题描述】:我需要制作一个 php 脚本来在 Google 日历上创建一个单一的事件。 我在设置客户端 ID、客户端密码、开发密钥和创建新事件时没有遇到任何问题。
我唯一的问题是 OAuth2,特别是我需要建立永久连接,而且我不想每次运行脚本时都进行身份验证。
实际上,通过这个脚本,我可以获得一个令牌和一个刷新令牌,但是我的令牌每小时都会过期,我不知道如何刷新它。我该如何编辑此代码来做到这一点? 我可以将令牌和刷新令牌都保存在某处并始终使用相同的数据吗?
我获得了一个未捕获的异常“Google_AuthException”,并带有消息“刷新 OAuth2 令牌时出错,消息:'“error”:“invalid_grant”
我已经在 *** 中阅读了有关此主题的其他一些帖子,但我仍然没有找到解决方案...:\
<?php
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_CalendarService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Calendar App");
$client->setClientId('xxxx');
$client->setClientSecret('yyy');
$client->setRedirectUri('http://www.zzzzzz');
$client->setDeveloperKey('kkk');
$client->setAccessType('offline');
$cal = new Google_CalendarService($client);
if (isset($_GET['logout']))
unset($_SESSION['token']);
if (isset($_GET['code']))
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
if (isset($_SESSION['token']))
//echo $_SESSION['token'];
//$client->setAccessToken($_SESSION['token']);
$authObj = json_decode($_SESSION['token']);
$accessToken = $authObj->access_token;
$refreshToken = $authObj->refresh_token;
$tokenType = $authObj->token_type;
$expiresIn = $authObj->expires_in;
echo 'access_token = ' . $accessToken;
echo '<br />';
echo 'refresh_token = ' . $refreshToken;
echo '<br />';
echo 'token_type = ' . $tokenType;
echo '<br />';
echo 'expires_in = ' . $expiresIn;
if(!empty($cookie))
$client->refreshToken($this->Cookie->read('token'));
if ($client->getAccessToken())
$calList = $cal->calendarList->listCalendarList();
$_SESSION['token'] = $client->getAccessToken();
else
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
// Creation of a single event
$event = new Google_Event();
$event->setSummary($event_name);
$event->setLocation('');
....
?>
非常感谢您的支持!
【问题讨论】:
【参考方案1】:尝试删除 setDeveloperKey(),这对我造成了一些问题,似乎不需要。
【讨论】:
【参考方案2】:我之前收到此错误是因为我尝试了两次身份验证。
既然你有这条线:
if (isset($_GET['code']))
当代码在查询字符串中时,无论您是否已经通过身份验证,它都会尝试进行身份验证。在尝试(重新)身份验证之前尝试检查 SESSION 令牌是否存在。
【讨论】:
谢谢。这个答案为我解决了问题。【参考方案3】:此页面https://developers.google.com/accounts/docs/OAuth2WebServer#offline 解释了刷新令牌的工作原理,以及如何使用它通过原始 http 获取新的访问令牌。
从这个问题How to refresh token with Google API client?这里是php等价物
here is the snippet to set token, before that make sure the access type should be set to offline
if (isset($_GET['code']))
$client->authenticate();
$_SESSION['access_token'] = $client->getAccessToken();
To refresh token
$google_token= json_decode($_SESSION['access_token']);
$client->refreshToken($google_token->refresh_token);
this will refresh your token, you have to update it in session for that you can do
$_SESSION['access_token']= $client->getAccessToken()
调试中 按照这三个步骤调试任何 oauth 应用程序
确保您已阅读 https://developers.google.com/accounts/docs/OAuth2 以及相应的子页面(webapp、javascript 等),具体取决于您使用的 oauth 风格。如果您不了解应用程序在做什么,您将无法调试应用程序。
使用位于https://developers.google.com/oauthplayground/ 的 Oauth Playground 完成 Oauth 步骤并最终进行 Google API 调用。这将确认您的理解并向您展示 http 调用和响应的样子
使用 tracking/logging/proxy 等来跟踪来自您的应用程序的实际 http 流量。将此与您在第 2 步中观察到的情况进行比较。这应该可以告诉您问题出在哪里。
【讨论】:
感谢您的回答,但我仍然坚持这个问题。现在我得到一个“刷新 OAuth2 令牌时出错,错误”invalid_request“ 我已经以这种方式编辑了初始代码: if (isset($_GET['code'])) $client->authenticate(); $_SESSION['access_token'] = $client->getAccessToken(); header('位置:http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']); $google_token= json_decode($_SESSION['access_token']); $client->refreshToken($google_token->refresh_token); $_SESSION['access_token']= $client->getAccessToken(); 首先我已经用这种方式定义了一个带有令牌及其刷新令牌的硬编码 JSON。 $arr = array('access_token' => 'yz...', 'refresh_token' => 'xyz', 'token_type' => 'Bearer', 'expires_in' => 3600, 'created' => ... ); $_SESSION['token'] = json_encode($arr);我不明白什么时候必须刷新令牌。提前致谢 我不会看你的代码(我不懂php)。我已经用一些关于如何调试此类问题的提示更新了我的答案 @Roberto:你有没有找到解决“刷新 OAuth2 令牌时出错”的方法?我有同样的问题。谢谢!以上是关于无法在 PHP 中刷新 OAuth2 令牌,授权无效的主要内容,如果未能解决你的问题,请参考以下文章
Spring oauth2 刷新令牌 - 无法将访问令牌转换为 JSON
在 Oauth2 隐式授权流和第 3 方 cookie 中刷新令牌