Система единого входа в Google Apps Marketplace: автономный доступ

Наше приложение широко интегрировано со службами Google, такими как Почта, Контакты, Календарь и т. Д. И для всех этих служб Google нам нужен постоянный доступ к данным пользователя, не спрашивая разрешения у пользователя каждый раз, когда нам нужно получить наше приложение с данными из Google. Очень важно иметь мгновенный доступ к данным пользователя, когда мы синхронизируем контакты, календарь или получаем доступ к почте через Google IMAP. Мы также предоставляем доступ к нашему приложению из любой службы Google через систему единого входа (SSO). И тут у нас беда. Мы просим пользователей, которые устанавливают наше приложение, получить "автономный" доступ к своим данным. Таким образом, мы можем получить доступ к их данным мгновенно, когда мы запускаем наши сценарии синхронизации и т. Д. Первый раз пользователь предоставляет доступ к нашему приложению (через 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();
}

Может ли кто-нибудь помочь нам понять это поведение? Или, может быть, кто-то даже знает, как заставить его не запрашивать у пользователя «офлайн-доступ» каждый раз, когда он обращается к приложению?


person maghoth    schedule 20.06.2014    source источник


Ответы (2)


Это потому, что для вашего запроса на утверждение установлено значение «force:

 $client->setApprovalPrompt('force');

Используйте силу только в том случае, если вам нужно повторно выпустить токен обновления. Есть странный побочный эффект, когда у пользователя снова и снова запрашивается офлайн-доступ.

person Philippe Laval    schedule 22.06.2014
comment
Большое спасибо! $client->setApprovalPrompt('auto'); Работает, как и ожидалось, я просто также переместил проверку "refresh_token" в другую часть кода (пропустил ее для пользователей, учетные данные которых уже сохранены в БД - это была моя большая ошибка). - person maghoth; 23.06.2014

Мы используем служебные учетные записи, которые предоставляют нам автономный доступ для любого пользователя в установленном домене (для выбранной организационной единицы). В зависимости от того, что вы пытаетесь сделать, это может быть вариантом для вас.

https://developers.google.com/drive/web/service-accounts

person PNC    schedule 22.06.2014