我将HWIO Bundle用于google api,当我收到来自google refreshToken=null的响应时,为什么?如何刷新代币
oAuthToken = {HWI'Bundle'OAuthBundle'Security'Core'Authentication'Token'OAuthToken} [11]
accessToken = "ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg"
rawToken = {array} [4]
access_token = "ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg"
token_type = "Bearer"
expires_in = 3578
id_token = "xxxxx"
refreshToken = null
expiresIn = 3578
createdAt = 1468957368
tokenSecret = null
resourceOwnerName = null
因为在google/apiclient中,函数中的"version":"1.1.7"需要refresh_token
public function getRefreshToken()
{
if (array_key_exists('refresh_token', $this->token)) {
return $this->token['refresh_token'];
} else {
return null;
}
}
这是我的访问令牌
{"access_token":"ya29.Ci8lA1JTu9CB81dOFy-nzszViRgCI2CvvKVrCd0Lq-8I0QR_dIrl-_7RccdGt1Islg","token_type":"Bearer","expires_in":3578,"id_token":"xxxx","created":1468957368}
没有刷新令牌,因为从谷歌得到refreshToken=null或需要用密钥刷新令牌设置null,或者这不符合要求?
$isExpired = $client->isAccessTokenExpired(); // true (bool Returns True if the access_token is expired.)
$refresh = $client->getRefreshToken(); //null because not gahe refresh token
$client->getGoogleClient()->setAccessType ("offline"); //some recomendation
$client->getGoogleClient()->setApprovalPrompt ("force"); //some recomendation
$isAgainExpired = $client->isAccessTokenExpired(); // still true (expired)
仍然有异常-The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.
如何刷新令牌以及如何使用令牌获取刷新令牌,用于刷新令牌?
我尝试
- 在我的代码中也是
$client = new Google_Client()
,但在包装器中,在构造函数中 我从HWIO捆绑包获得访问令牌:
hwi_oauth: connect: account_connector: app.provider.user_provider firewall_name: secured_area resource_owners: google: type: google client_id: xxx.apps.googleusercontent.com client_secret: xxx scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive"
在我获得访问令牌后,我将其设置在DB中。然后在Action中,我为googleapi(新的GoogleClient())创建包装器,并将我从DB中的accesss令牌设置给这个客户端。如何刷新我的访问令牌?我尝试在实际操作中使用函数google api lib setAccessType和setApprovalPrompt,但不影响
public function __construct(array $config, LoggerInterface $symfonyLogger = null)
{
// True if objects should be returned by the service classes.
// False if associative arrays should be returned (default behavior).
$config['use_objects'] = true;
$client = new 'Google_Client($config);
if ($symfonyLogger) {
//BC for Google API 1.0
if (class_exists(''Google_Logger_Psr')) {
$googleLogger = new 'Google_Logger_Psr($client, $symfonyLogger);
$client->setLogger($googleLogger);
} else {
$client->setLogger($symfonyLogger);
}
}
$client -> setApplicationName($config['application_name']);
$client -> setClientId($config['oauth2_client_id']);
$client -> setClientSecret($config['oauth2_client_secret']);
$client -> setRedirectUri($config['oauth2_redirect_uri']);
$client -> setDeveloperKey($config['developer_key']);
$client -> setAccessType ($config['access_type']);
$client -> setApprovalPrompt ($config['approval_prompt']);
$this -> client = $client;
}
配置这是:
happy_r_google_api:
application_name: carbon-quanta-137312
oauth2_client_id: xxxx.apps.googleusercontent.com
oauth2_client_secret: xxx
oauth2_redirect_uri: null
developer_key: null
site_name: aog.local.com
access_type: offline
approval_prompt: force
如果在操作中,我为谷歌客户端设置了一些参数,如果我添加constructorI,这是一样的,那么我做错了什么?
refresh_token仅在第一个请求时返回。当您第二次刷新访问令牌时,它会返回除refresh_token之外的所有内容,并且当第二次出现这种情况时,file_put_contents会删除refresh_token。
按照以下方式修改代码将在原始访问令牌中与新的访问令牌合并(请参见:array_merge)。这样,您就可以保留refresh_token以备将来请求。我已经向谷歌提交了以下修复程序,希望他们能在某个时候更新。
有关更多信息,请参阅文档
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$newAccessToken = $client->getAccessToken();
$accessToken = array_merge($accessToken, $newAccessToken);
file_put_contents($credentialsPath, json_encode($accessToken));
}
Arithran已经回答了一半的问题。
只有在您第一次授权您的帐户时,才会发送过期令牌。在那之后,您将不再收到它,这就是为什么您需要从一开始就保存它,然后在每次刷新时,合并新旧阵列。
答案的另一半是如何删除并再次接收该令牌,否则每次都需要使用新的谷歌帐户进行测试。
- 转到您的帐户安全设置:https://www.google.com/settings/u/1/security.
- 滚动至"授权应用程序和网站"部分,然后单击"全部查看"
- 然后"取消访问"您的应用程序
- 提出新的OAuth2请求。这将返回一个refresh_token
请记住将access_type=offline
添加到您的请求
在OAuth 2.0协议中,您的应用程序请求授权以访问由作用域标识的资源,并且假设用户经过身份验证和批准,则应用程序将接收允许其访问这些资源的短暂访问令牌,以及(可选)刷新令牌以允许长期访问。
刷新令牌的想法是,如果访问令牌被破坏,因为它是短暂的,攻击者滥用它的窗口有限。
刷新令牌如果被破坏,则毫无用处,因为攻击者除了需要刷新令牌外,还需要客户端id和机密才能获得访问令牌。
代币可能停止工作的原因:
- 用户已吊销访问权限
- 该代币已经六个月没有使用了
- 用户更改了密码,令牌包含Gmail、日历、联系人或Hangouts范围
- 用户帐户已超过一定数量的令牌请求
目前,每个客户端每个用户帐户的刷新令牌限制为25个。如果达到限制,创建新令牌会自动使最旧的令牌失效,而不会发出警告。此限制不适用于服务帐户。
下面是一个相关的SO票证,讨论为什么获取NULL令牌:获取NULL刷新令牌
我理解。我从HWIO捆绑包中获得访问令牌,并在配置中添加HWIO捆绑集access_type:offline,approvel_prompt:force,作为响应,我有刷新令牌非空
google:
type: google
client_id: xxx
client_secret: xxx
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive"
options:
access_type: offline
approval_prompt: force