我想从谷歌获取访问令牌。谷歌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
}
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;
}
我找了一个漫长的夜晚,这个很管用:
修改了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);
为了获得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,但如果您的用户可能想要使用多个谷歌帐户进行身份验证(即,您不使用此帐户进行登录/身份验证),则它很有用。