我们的应用程序与邮件,通讯录,日历等Google服务广泛集成。对于所有这些Google服务,我们需要永久访问用户的数据,而不是每次我们需要提取应用程序时都要求用户获得许可来自Google的数据。当我们通过Google IMAP同步联系人,日历或访问邮件时,立即访问用户数据非常重要。 我们还通过单点登录(SSO)从任何Google服务访问我们的应用。在这里我们遇到了麻烦。 我们要求安装我们的应用程序的用户“脱机”访问他们的数据。因此,当我们运行同步脚本等时,我们可以立即访问他们的数据。 第一次用户授予访问我们的应用程序的权限(通过SSO,当它点击我们的应用程序图标时),它被要求授予访问我们需要的所有数据API - 联系人,电子邮件,日历等。一切顺利,用户登录我们的应用程序。但是当用户下次访问我们的应用程序时(通过SSO相同),它会被要求授予“具有脱机访问权限”。这很奇怪,因为第一次用户不会被要求这样做。每次询问用户“离线访问”也不好看。为什么我们认为这种行为很奇怪是因为一旦用户已经授予访问权限。那么为什么一次又一次地被问到这个问题呢?
我们用于SSO的代码如下:
$clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";
$clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$callback = "https://our_domain/callback";
$scopes = array(
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/drive.readonly.metadata",
"https://www.googleapis.com/auth/calendar",
"https://www.google.com/m8/feeds",
"https://www.googleapis.com/auth/tasks",
"https://www.googleapis.com/auth/admin.directory.user.readonly",
"https://mail.google.com/"
);
// $params is a list of GET and POST parameters
if (empty($params['code']))
{
$_SESSION['GOOGLE_SSO_STATE'] = md5(uniqid(rand(), true));
$client = new Google_Client();
$client->setClientId($clientId);
$client->setRedirectUri($callback);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setState($_SESSION['GOOGLE_SSO_STATE']);
$client->setScopes($scopes);
$url = $client->createAuthUrl();
echo "<script> top.location.href='" . $url . "'</script>";
exit;
}
if (!empty($params['code']) && !empty($params['state']) && $params['state'] == $_SESSION['GOOGLE_SSO_STATE'])
{
unset($_SESSION['GOOGLE_SSO_STATE']);
$client = new Google_Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($callback);
$credentials = $client->authenticate();
// we need refresh token so we can exchange it for new access token when the current ones expires
if (!isset($credentials_['refresh_token']))
{
echo "Wrong credentials received";
exit;
}
$client = new Google_Client();
$client->setUseObjects(true);
$client->setAccessToken($credentials);
$userInfoService = new Google_Oauth2Service($client);
$userInfo = $userInfoService->userinfo->get();
echo $userInfo->getId();
}
任何人都可以帮助我们理解这种行为吗?或者有人甚至知道如何在每次访问应用程序时都要求用户“离线访问”?
答案 0 :(得分:1)
这是因为您的批准提示设置为&#34;强制:
$client->setApprovalPrompt('force');
仅在需要重新发出刷新令牌时使用强制。有一种奇怪的副作用会一次又一次地要求用户进行离线访问。
答案 1 :(得分:0)
我们使用服务帐户为我们提供已安装域中任何用户的离线访问权限(针对所选的组织单位)。根据您的目的,这可能是您的选择。