我想从谷歌获取访问令牌。谷歌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
}

当前回答

为了获得refresh_token,你需要在OAuth请求URL中包含access_type=offline。当一个用户第一次验证时,你会得到一个非空的refresh_token以及一个过期的access_token。

如果遇到这样的情况,用户可能会重新验证您已经拥有身份验证令牌的帐户(如上面提到的@SsjCosty),则需要从谷歌获取令牌用于哪个帐户的信息。要做到这一点,请将概要文件添加到作用域。使用OAuth2 Ruby宝石,你的最终请求可能看起来像这样:

client = OAuth2::Client.new(
  ENV["GOOGLE_CLIENT_ID"],
  ENV["GOOGLE_CLIENT_SECRET"],
  authorize_url: "https://accounts.google.com/o/oauth2/auth",
  token_url: "https://accounts.google.com/o/oauth2/token"
)

# Configure authorization url
client.authorize_url(
  scope: "https://www.googleapis.com/auth/analytics.readonly profile",
  redirect_uri: callback_url,
  access_type: "offline",
  prompt: "select_account"
)

注意,作用域有两个空格分隔的条目,一个用于对谷歌Analytics的只读访问,另一个仅用于配置文件,这是OpenID Connect标准。

这将导致谷歌在get_token响应中提供一个名为id_token的附加属性。要从id_token中获取信息,请查看谷歌文档中的此页面。有一些google提供的库可以为您验证和“解码”这些代码(我使用了Ruby google-id-token gem)。解析后,子参数实际上是唯一的谷歌帐户ID。

值得注意的是,如果您更改了作用域,对于已经使用原始作用域进行身份验证的用户,您将再次获得一个刷新令牌。这很有用,如果你已经有一群用户,不想让他们都在谷歌中取消应用程序的认证。

哦,最后一点注意:您不需要prompt=select_account,但如果您的用户可能想要使用多个谷歌帐户进行身份验证(即,您不使用此帐户进行登录/身份验证),则它很有用。

其他回答

现在谷歌已经拒绝了这些参数在我的请求(access_type,提示)…:(并且根本没有“撤销访问权限”按钮。我很沮丧,因为回到我的refresh_token lol

更新: 我在这里找到了答案:D,您可以通过请求获得刷新令牌 https://developers.google.com/identity/protocols/OAuth2WebServer

curl -H "Content-type:application/x-www-form-urlencoded" \ https://accounts.google.com/o/oauth2/revoke?token={牌} 令牌可以是访问令牌,也可以是刷新令牌。如果令牌是访问令牌,并且它有相应的刷新令牌,则刷新令牌也将被撤销。 如果成功地处理了撤销,则响应的状态码为200。对于错误条件,将返回状态代码400和错误代码。

为了在每次验证时获得新的refresh_token,在仪表板中创建的OAuth 2.0凭据类型应该是“Other”。同样如上所述,在生成authURL时应该使用access_type='offline'选项。

当使用类型为“Web application”的凭据时,prompt/approval_prompt变量的组合将不起作用——您仍然只能在第一个请求上获得refresh_token。

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

修改了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);

My solution was a bit weird..i tried every solution i found on internet and nothing. Surprisely this worked: delete the credentials.json, refresh, vinculate your app in your account again. The new credentials.json file will have the refresh token. Backup this file somewhere. Then keep using your app until the refresh token error comes again. Delete the crendetials.json file that now is only with an error message (this hapenned in my case), then paste you old credentials file in the folder, its done! Its been 1 week since ive done this and had no more problems.

refresh_token仅在用户第一次授权时提供。后续的授权,比如您在测试OAuth2集成时所做的授权,将不会再次返回refresh_token。:)

进入可以访问您帐户的应用程序页面: https://myaccount.google.com/u/0/permissions。 在第三方应用程序菜单下,选择您的应用程序。 单击“删除访问”,然后单击“确定”确认 下一个OAuth2请求将返回一个refresh_token(前提是它还包括'access_type=offline'查询参数)。

或者,您可以将查询参数prompt=consent&access_type=offline添加到OAuth重定向(参见谷歌的OAuth 2.0 for Web服务器应用程序页面)。

这将提示用户再次授权应用程序,并总是返回一个refresh_token。