获取刷新令牌Google API


76

我的代码无法获得刷新令牌。我只能获取访问令牌,令牌类型等,我已经按照一些教程进行了操作,例如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_tokentoken_typeid_tokenexpires_in


1
/ *检查这个环节的工作对我来说@Nobert解决方案* / stackoverflow.com/questions/10827920/...
Manmeet库拉纳

Answers:


107

通过将其添加到您的url参数中找出

Approval_prompt =力

更新:

使用access_type=offline&prompt=consent代替。

approval_prompt=force不再起作用 https://github.com/googleapis/oauth2client/issues/453


12
为什么不能与Auto一起使用?我不希望用户每次都授予许可。我怎么能过来呢?
Harsha MV

6
因为reresh令牌仅在第一次授予应用程序权限时返回。之后,所有的请求approval_prompt=auto都不再具有refresh_token了。检查此答案以获取更详细的说明stackoverflow.com/a/10857806/987864
Daan 2015年

4
您需要access_type=offline在所有情况下都需要refresh_token
Daan

7
已编辑有效答案的答案,因为此答案已过时,似乎不再起作用。我花了大量时间尝试此操作,因为有多个地方说要使用此方法。我终于阅读了文档(我应该先完成该文档),并说您必须使用prompt=consent。参考:developers.google.com/identity/protocols/...
Goblinlord

8
@Daan和@Goblinlord都是正确的,即使阅读了他们的评论后,我也为此感到困惑。实际上,我们都需要access_type=offline&prompt=consent。否则,refresh_token将不存在。
Noitidart '16

62

如果我可以扩展user987361的答案:

从OAuth2.0文档的脱机访问部分:

当您的应用程序收到刷新令牌时,存储该刷新令牌以供将来使用很重要。如果您的应用程序丢失了刷新令牌,则在获取另一个刷新令牌之前,它必须重新提示用户同意。如果您需要重新提示用户同意,请approval_prompt 在授权代码请求中包含参数,并将值设置为 force

所以,当你已经授予访问权限,对于后续请求grant_typeauthorization_code将不会返回refresh_token,即使access_type被设置为offline在同意页面的查询字符串。

为了获得上述的报价如前所述 refresh_token已经接受后,您将需要发送过提示,您可以通过设置做你的用户返回approval_promptforce

干杯,

PS此更改也在博客文章中宣布。


3
我要补充一点,如果您丢失了 refresh token密码或用户撤消了访问权限,则只需要获取密码即可。否则,您可以继续使用它refresh token来获取new access token
jeteon 2015年

1
我有一个CMS,不同的用户在其中使用不同的Google帐户来连接到Analytics API。但是,有时有几个用户可以使用相同的公司google帐户进行连接,但每个用户都希望访问不同的Analytics(分析)帐户。只有第一个接收刷新令牌,而其他所有接收不到的令牌,因此必须每小时重新连接一次。是否有办法获取SAME刷新令牌以进行后续身份验证,而不是仅在一个小时内到期的access_token?
SsjCosty 2015年

是。去做就对了。发送请求时,您将获得访问令牌和刷新令牌。
bossylobster

我在努力获取一个refresh_token,而您通过解决方案启发了我!“因此,当您已经授予访问权限时,即使在同意页面的查询字符串中将access_type设置为脱机,后续对authorization_code的grant_type的请求也不会返回refresh_token。
Cristiana S. Parada

12

这就是access_type=offline你想要的。

这将在用户首次授权应用程序时返回刷新令牌。随后的调用不会强制您重新批准该应用(approval_prompt=force)。

查看更多详细信息:https : //developers.google.com/accounts/docs/OAuth2WebServer#offline


1
该链接页面指出Google客户端将在访问令牌到期时负责更新访问令牌(该更新令牌可能在机密XML文件中),但是没有显示如何检测到访问令牌已更改,以便它可以保存在应用程序中以供下次访问。是否有一个回调,或者应用程序应该始终检查它执行的每个远程访问的访问令牌是否都已更改?
杰森

10

这是使用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

8

对于我们的应用程序,我们必须同时使用这两个参数access_type=offline&prompt=consent。 对我们approval_prompt=force 没有


1
谢谢Ricky,这也是我的工作。我认为,较旧的答案暗示approval_prompt=force当时可能是正确的,但不再起作用。这里有一些讨论:github.com/google/oauth2client/issues/453
Mike Morearty

7

嗨,我按照以下步骤操作,我已经能够获取刷新令牌。

授权流程有两个步骤。

  1. 是使用https://accounts.google.com/o/oauth2/auth?URL获取授权码。

    为此,将发送后请求,​​并提供以下参数。'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline'提供以上内容将收到授权码。

  2. 使用https://accounts.google.com/o/oauth2/token?URL检索AcessToken和RefreshToken 。为此,将发送后请求,​​并提供以下参数。

    “ code”:代码,“ client_id”:CID,“ client_secret”:CSECRET,“ redirect_uri”:REDIRECT,“ grant_type”:“ authorization_code”,

因此,在您第一次尝试授权后,便可以获取Refresh令牌。后续尝试将不提供刷新令牌。如果再次需要令牌,请撤消应用程序中的访问权限。

希望这可以帮助某人加油:)




0

对于使用PHP的Google API客户端库并寻求脱机访问和刷新令牌的用户,在撰写本文时,请注意文档中显示了错误的示例。

目前显示:

$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请求已将其从roval_prompt = force更改为提示= consent。因此,将setter方法从setApprovalPrompt更改为setPrompt遵循自然的惯例-但它不在DOCS中!!!我发现至少。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.