我无法使用我的代码获取刷新令牌。我只能获取我的访问令牌、令牌类型等,我遵循了一些教程,例如将 access_type=offline
放在我的登录 URL 上:
echo "<a href='https://accounts.google.com/o/oauth2/auth?"
. "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
. "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
. "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";
以及我获取访问令牌的字段:
$fields=array(
'code'=> urlencode($authcode),
'client_id'=> urlencode($clientid),
'client_secret'=> urlencode($clientsecret),
'redirect_uri'=> urlencode($redirecturi),
'grant_type'=> 'authorization_code',
);
但我无法获取 refresh_token,只有 access_token、token_type、id_token 和 expires_in。
通过将此添加到您的 url 参数中找到
批准提示=强制
更新:
请改用 access_type=offline&prompt=consent
。
approval_prompt=force
不再有效https://github.com/googleapis/oauth2client/issues/453
如果我可以扩展 user987361 的答案:
从 OAuth2.0 文档的 offline access 部分:
当您的应用程序收到刷新令牌时,存储该刷新令牌以供将来使用非常重要。如果您的应用程序丢失了刷新令牌,则必须重新提示用户同意,然后才能获取另一个刷新令牌。如果您需要重新提示用户同意,请在授权码请求中包含approval_prompt参数,并将值设置为强制。
因此,当您已授予访问权限时,后续对 authorization_code
的 grant_type
的请求将不会返回 refresh_token
,即使在同意页面的查询字符串中将 access_type
设置为 offline
。
如上面的引用所述,为了在收到 新的 refresh_token
后获得一个,您需要通过提示将您的用户发回,您可以通过将 approval_prompt
设置为force
。
干杯,
PS 此更改也在 blog post 中公布。
refresh token
。否则,您可以继续使用相同的 refresh token
来获取新的 access token
。
您想要的是 access_type=offline
。
这将在用户首次授权应用程序时返回刷新令牌。后续调用不会强制您重新批准应用程序 (approval_prompt=force
)。
查看更多详细信息:https://developers.google.com/accounts/docs/OAuth2WebServer#offline
这是使用 google 官方 SDK 在 PHP 中的完整代码
$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access
对于我们的应用程序,我们必须使用这两个参数 access_type=offline&prompt=consent
。 approval_prompt=force
对我们不起作用
approval_prompt=force
的较旧答案在当时可能是正确的,但不再有效。这里有一些讨论:github.com/google/oauth2client/issues/453
嗨,我按照以下步骤操作,我已经能够获得刷新令牌。
授权流程有两个步骤。
是使用 https://accounts.google.com/o/oauth2/auth 获取授权码吗?网址。为此,发送一个提供以下参数的发布请求。 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline' 提供上述将收到一个授权码。使用 https://accounts.google.com/o/oauth2/token 检索 AcessToken 和 RefreshToken?网址。为此,发送一个提供以下参数的发布请求。 “code”:代码,“client_id”:CID,“client_secret”:CSECRET,“redirect_uri”:REDIRECT,“grant_type”:“authorization_code”,
因此,在您第一次尝试授权权限后,您将能够获得刷新令牌。后续尝试将不会提供刷新令牌。如果您再次想要令牌,请撤销您应用程序中的访问权限。
希望这会帮助有人欢呼:)
OAuth 在实模式下有两种情况。正常和默认的访问方式称为在线访问。在某些情况下,您的应用程序可能需要在用户不在时访问 Google API,这是离线场景。第一次授权码交换时离线场景下获取刷新令牌。
所以你可以得到referh_token是一些场景,不是全部。
您可以拥有 https://developers.google.com/identity/protocols/OAuth2WebServer#offline 中的内容。
自 2016 年 3 月起,使用 prompt=consent
重新生成 Google API 刷新令牌。
如 https://github.com/googleapis/oauth2client/issues/453 中所述,
approval_prompt=force 已替换为 prompt=none|consent|select_account
对于那些使用 PHP 的 Google API Client Library 并寻求离线访问和刷新令牌的人,请注意在撰写本文时文档显示的示例不正确。
目前它显示:
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true); // incremental auth
来源:https://developers.google.com/identity/protocols/OAuth2WebServer#offline
所有这些都很好——除了一件
$client->setApprovalPrompt("consent");
经过一番推理,我将此行更改为以下内容,一切正常
$client->setPrompt("consent");
这是有道理的,因为使用 HTTP 请求时,它已从approval_prompt=force 更改为prompt=consent。因此,将 setter 方法从 setApprovalPrompt 更改为 setPrompt 遵循自然约定 - 但它不在文档中!!!至少我发现了。
approval_prompt=auto
的请求都不再具有 refresh_token。查看此答案以获取更详细的说明stackoverflow.com/a/10857806/987864access_type=offline
prompt=consent
。参考:developers.google.com/identity/protocols/…access_type=offline&prompt=consent
。否则refresh_token
将不存在。