我想从谷歌获取访问令牌。谷歌API说,要获得访问令牌,将代码和其他参数发送到令牌生成页面,响应将是一个JSON对象,如:

{
"access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"
}

但是,我没有收到刷新令牌。我的回答是:

{
 "access_token" : "ya29.sddsdsdsdsds_h9v_nF0IR7XcwDK8XFB2EbvtxmgvB-4oZ8oU",
"token_type" : "Bearer",
"expires_in" : 3600
}

当前回答

1. 如何获得'refresh_token' ?

解决方案:access_type='offline'选项应该在生成authURL时使用。 来源:为Web服务器应用程序使用OAuth 2.0

2. 但即使有'access_type=offline',我没有得到'refresh_token' ?

解决方案:请注意,您只会在第一次请求时获得它,所以如果您将它存储在某个地方,并且在您的代码中有一个条款可以在上次过期后获得新的access_token时覆盖它,那么请确保不要覆盖这个值。

From谷歌Auth Doc:(this value = access_type)

该值指示谷歌授权服务器返回一个 刷新令牌和访问令牌,第一次您的应用程序 将授权代码交换为令牌。

如果你再次需要'refresh_token',那么你需要按照Rich Sutton的回答中所写的步骤删除对应用程序的访问。

其他回答

要使用postman获取刷新令牌,下面是一个配置示例

预期响应

设置这个将导致刷新令牌每次都被发送:

$client->setApprovalPrompt('force');

下面给出一个例子(php):

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("email");
$client->addScope("profile"); 
$client->setAccessType('offline');
$client->setApprovalPrompt('force');

这给我带来了一些困惑,所以我想分享一下我艰难的经历:

当您使用access_type=offline和approval_prompt=force参数请求访问时,您应该收到一个访问令牌和一个刷新令牌。访问令牌在收到后不久就会过期,您需要刷新它。

您正确地发出了获取新访问令牌的请求,并收到了具有新访问令牌的响应。我还对没有获得新的刷新令牌感到困惑。然而,这就是它的意义所在,因为您可以反复使用相同的刷新令牌。

我认为其他一些答案假设您出于某种原因想要获得一个新的刷新令牌,并建议您重新授权用户,但实际上,您不需要这样做,因为您拥有的刷新令牌将一直工作,直到用户撤销。

我找了一个漫长的夜晚,这个很管用:

修改了admin-sdk中的user-example.php

$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$authUrl = $client->createAuthUrl();
echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";

然后在重定向url处获得代码 用代码进行身份验证并获得刷新令牌

$client()->authenticate($_GET['code']);
echo $client()->getRefreshToken();

你现在应该把它存储;)

当你的accesskey超时就做

$client->refreshToken($theRefreshTokenYouHadStored);

For me I was trying out CalendarSampleServlet provided by Google. After 1 hour the access_key times out and there is a redirect to a 401 page. I tried all the above options but they didn't work. Finally upon checking the source code for 'AbstractAuthorizationCodeServlet', I could see that redirection would be disabled if credentials are present, but ideally it should have checked for refresh token!=null. I added below code to CalendarSampleServlet and it worked after that. Great relief after so many hours of frustration . Thank God.

if (credential.getRefreshToken() == null) {
    AuthorizationCodeRequestUrl authorizationUrl = authFlow.newAuthorizationUrl();
    authorizationUrl.setRedirectUri(getRedirectUri(req));
    onAuthorization(req, resp, authorizationUrl);
    credential = null;
}