клиент не авторизован для получения токенов доступа с помощью этого метода ошибка учетной записи службы - PullRequest
0 голосов
/ 23 ноября 2018

Это была такая большая головная боль - заставить мою учетную запись службы проходить аутентификацию в том же веб-приложении, где у меня есть пользователи, которые также входят в систему через oauth2.

Так что мне интересно, это вообще возможно?

Если нет, стоит ли просто придерживаться учетной записи службы?Нужно ли аутентифицировать пользователей по старому стилю?Хаха

Спасибо.

Что касается служебной учетной записи, я включил широкое делегирование домена , включил клиентский ключ + область API в моей консоли администратора G Suite и получил пример php с работающим API книг.,Однако всякий раз, когда я пробую любой другой API, кроме книг, я получаю сообщение об ошибке,

клиент не авторизован для получения токенов доступа, используя этот метод

ОБНОВЛЕНИЕ: Я попытался использовать пример @ dalmto и добавил несколько строк для проверки API gmail, например:

putenv('GOOGLE_APPLICATION_CREDENTIALS=credentials.json');

$user = 'email@domain.de';

function getGoogleClient() {
    return getServiceAccountClient();
}

function getServiceAccountClient() {
    try {
        // Create and configure a new client object.
        $client2 = new Google_Client();
        $client2->useApplicationDefaultCredentials();
        $client2->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/admin.directory.user.readonly','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
        $client2->setAccessType('offline');
        $client2->setSubject($user);
        return $client2;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);

Но сейчас я просто получаю ошибки "400: Bad Request"

РЕДАКТИРОВАТЬ : После еще нескольких копаний появляется примечание: ' failedPrecondition ' - есть какая-нибудь идея, которая может быть предварительным условием?Я разрешил следующие области для клиента в моей консоли администратора:

hxxps: //www.googleapis.com/auth/gmail.metadata, hxxps: //www.googleapis.com/auth / userinfo.email, hxxps: //www.googleapis.com/auth/userinfo.profile, hxxps: //www.googleapis.com/auth/gmail.modify, hxxps: //www.googleapis.com/auth/gmail.readonly,
hxxps: //www.googleapis.com/auth/gmail.labels,
hxxps: //mail.google.com/

И включил API ивключил область действия на экране «OAuth Consent»

DWD также включен: Снимок экрана «Обзор учетной записи службы»

EDIT2 : Хорошо, я нашелотсутствующим предварительным условием был «setSubject».

Как только я добавил, что это пошло еще дальше, но все еще не удалось снова на '"error": "unauthorized_client",\n "error_description": "Client is unauthorized to retrieve access tokens using this method.'

К вашему сведению: при создании учетной записи службы я назначил ей роль «проект -> владелец».Этого достаточно?Нужно ли добавлять еще?

EDIT3 : Я также только что проверил регистратор, и он говорит, что DWD включен .. Я на моем конце здесь хаха

   client: {
    adminState: {
     updateTime:  "2018-11-23T00:29:44.810Z"      
    }
    assertionMatchExistingGrant:  "MATCH_GRANT_DISABLED"     
    authType:  "PUBLIC_KEY"     
    brandId:  "aaaaaaaaaaaaaa"     
    clientId:  "aaaaaaaaaaaaaaaaaa"     
    consistencyToken:  "2018-11-23T00:29:44.953175Z"     
    creationTime:  "2018-11-23T00:29:44.810Z"     
    displayName:  "Client for servicemaint1"     
    domainWideDelegation:  "DELEGATION_ENABLED"     
    projectNumber:  "aaaaaaaaaaaaaaaa"     
    threeLeggedOauth:  "DISABLED"     
    updateTime:  "2018-11-23T00:29:44.953175Z"     
   }

РЕДАКТИРОВАТЬ 4: НАКОНЕЦ РАБОТЫ!

Так что я пробовал это в новом проекте, который я создал для тестирования все утро / вчера вечером.Но моя аутентификация пользователя oauth2 проходила через другой проект (где я также не мог заставить служебную учетную запись работать все утро / день вчерашнего дня).

Так или иначе, я заметил в: https://myaccount.google.com/permissions«Приложения с доступом к вашей учетной записи» - только мой старый проект / приложение было авторизовано.Поэтому я вернулся к своему первому проекту, создал новый файл идентификатора клиента учетной записи службы .json, и он, наконец, сработал для аутентификации обоих!:)

Я должен был разрешить это где-то дополнительно по линии, которую я не сделал со вторым проектом.

Еще раз спасибо.

EDIT5: Еще один быстрый вопрос - это правильный способ сделать это в стеке потока?С постоянно возвращаясь к редактированию?

Также для других, кто сталкивается с этим позже, вот мой полный блок аутентификации (извините, он немного длинный):

putenv('GOOGLE_APPLICATION_CREDENTIALS=maintenanceapp.json');

$user = 'xyz@abc.com';

function getGoogleClient() {
    return getServiceAccountClient();
}

function getServiceAccountClient() {
  $user = 'xyz@abc.com';
    try {
        // Create and configure a new client object.
        $client2 = new Google_Client();
        $client2->useApplicationDefaultCredentials();
        $client2->setScopes(['https://www.googleapis.com/auth/gmail.metadata','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.labels']);
        //$client2->setAccessType('offline');
        $client2->setSubject($user);
        return $client2;
    } catch (Exception $e) {
        echo "An error occurred: " . $e->getMessage();
    }
}

$newGoogleClient = getGoogleClient();

$service3 = new Google_Service_Gmail($newGoogleClient);
$results3 = $service3->users_labels->listUsersLabels($user);


 /*************************************************
  * Ensure you've downloaded your oauth credentials
  ************************************************/
 if (!$oauth_credentials = getOAuthCredentialsFile()) {
   echo missingOAuth2CredentialsWarning();
   return;
 }
 /************************************************
  * NOTICE:
  * The redirect URI is to the current page, e.g:
  * http://localhost:8080/idtoken.php
  ************************************************/
 $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
 $client = new Google_Client();
 // USER AUTH
 $client->setAuthConfig($oauth_credentials);
 $client->setRedirectUri($redirect_uri);
 $client->setScopes(array('https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/calendar'));
 $client->setApprovalPrompt('auto');
 $client->setAccessType('offline');
 $plus = new Google_Service_Plus($client);

 /************************************************
  * If we're logging out we just need to clear our
  * local access token in this case
  ************************************************/
 if (isset($_REQUEST['logout'])) {
   unset($_SESSION['id_token_token']);
 }

 /************************************************
  * If we have a code back from the OAuth 2.0 flow,
  * we need to exchange that with the
  * Google_Client::fetchAccessTokenWithAuthCode()
  * function. We store the resultant access token
  * bundle in the session, and redirect to ourself.
  ************************************************/
 if (isset($_GET['code'])) {
   $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
   // store in the session also
   $_SESSION['id_token_token'] = $token;
   // redirect back to the example
   header('Location: https://abc.de/index.php');
   // return;
 }
 /************************************************
   If we have an access token, we can make
   requests, else we generate an authentication URL.
  ************************************************/
 if (
   !empty($_SESSION['id_token_token'])
   && isset($_SESSION['id_token_token']['id_token'])
 ) {
   $client->setAccessToken($_SESSION['id_token_token']);
 } else {
   $authUrl = $client->createAuthUrl();
   //header('Location: ' . $authUrl);
 }
 /************************************************
   If we're signed in we can go ahead and retrieve
   the ID token, which is part of the bundle of
   data that is exchange in the authenticate step
   - we only need to do a network call if we have
   to retrieve the Google certificate to verify it,
   and that can be cached.
  ************************************************/
 if ($client->getAccessToken()) {
   $token_data = $client->verifyIdToken();
 }

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018
response_type=code
client_id=348268306866-9dl0kdgn2f9bjhoge7pris1jo8u9si47.apps.googleusercontent.com
redirect_uri=https://degoo.com/me/googleoauth2callback
access_type=offline
scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/contacts.readonly
state={"RedirectUrl":"/me/chooseaccount","RegisterIfNotExists":true}

Это все, что мы знаем.

0 голосов
/ 23 ноября 2018

В консоли разработчика Google при создании проекта и учетных данных вы должны выбрать тип клиента, который вы собираетесь создать для какого типа приложения.

Существует несколько различных способов аутентификации в Google.

  • OAuth2 native
  • OAuth2 web
  • Мобильный
  • Сервисный аккаунт

Код для использования этих клиентов:тоже разные.Вы не можете создать веб-клиент OAuth2 и использовать его для кода, предназначенного для вызова учетной записи службы.

"клиент не авторизован для получения токенов доступа с помощью этого метода".

Означает именно это.Клиент, настроенный на консоли разработчика Google, либо не является клиентом учетной записи службы, либо используемый вами код не предназначен для клиента учетной записи службы.

Это мой serviceaccount.php пример.Если ваш код должен выглядеть примерно так, и вам нужно убедиться, что клиент, созданный вами на консоли разработчика Google, является клиентом учетной записи службы.

require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
 * Gets the Google client refreshing auth if needed.
 * Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
 * Initializes a client object.
 * @return A google client object.
 */
function getGoogleClient() {
    return getServiceAccountClient();
}
/**
 * Builds the Google client object.
 * Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
 * Scopes will need to be changed depending upon the API's being accessed. 
 * array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
 * List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
 * @return A google client object.
 */
function getServiceAccountClient() {
    try {   
        // Create and configure a new client object.        
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope([YOUR SCOPES HERE]);
        return $client;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

Консоль разработчика

В разделе «Клиенты» убедитесь, что используемый вами клиент находится в разделе ключей служебной учетной записи.Если нет, то это неправильный тип клиента и не будет работать с вашим кодом.Создайте новую учетную запись клиента службы и настройте делегирование по всему домену с этим идентификатором клиента.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...