API Google Таблиц возвращает «У вызывающего абонента нет разрешения» при использовании ключа сервера

89

Я создал ключ сервера в диспетчере API и попытался выполнить на своем Mac следующее:

curl 'https://sheets.googleapis.com/v4/spreadsheets/MySheetID?ranges=A1:B5&key=TheServerKeyIGeneratedInAPIManager'

Но вот что он возвращает:

{
 "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

Что я здесь делаю не так?

Instabrite
источник
4
Ключ предназначен для доступа к общедоступным данным, то, что вы делаете, требует аутентифицированного доступа.
DaImTo
В большинстве случаев возникает проблема с объемом. Пожалуйста, проверьте и проверьте, какие области требуются сценарию.
dpkrai96

Ответы:

119

Чтобы решить эту проблему, попробуйте:

  1. Создайте учетную запись службы: https://console.developers.google.com/iam-admin/serviceaccounts/
  2. В опциях создайте ключ: это ваш обычный client_secret.json - используйте его так же
  3. Сделайте владельцем роли для учетной записи службы (Имя участника = ID учетной записи службы = адрес электронной почты учетной записи службы, например: thomasapp@appname-201813.iam.gserviceaccount.com
  4. Скопируйте адрес электронной почты вашей учетной записи службы = идентификатор учетной записи службы.
  5. Просто зайдите в браузере на лист Google, с которым хотите взаимодействовать.
  6. Перейдите к ПОДЕЛИТЬСЯ в правом верхнем углу экрана.
  7. Перейдите в расширенные настройки и поделитесь им с адресом электронной почты вашей учетной записи службы, например: thomasapp@appname-201813.iam.gserviceaccount.com

У меня сработало :)

Томас Бодуэн
источник
1
это сработало для меня. кстати: в облачном админке Google перейдите в ... проект> IAM & Admin> Учетные записи служб .... Если вы настроили учетные записи служб, вы увидите специальное электронное письмо для каждой соответствующей учетной записи службы. Убедитесь, что вы также включили API Google Таблиц. Буквально, вы просто делитесь адресом электронной почты учетной записи службы с помощью кнопки «поделиться» в листе Google.
Джейсон Ф
1
да ... ключ в том, чтобы просто поделиться документом с электронной почтой учетной записи службы ....
user1102171
2
Ключ json сильно отличается от учетных данных json, которые я получил из руководства по быстрому запуску Java (для API таблиц). Как мне это реализовать?
Кардинал - Восстановите Монику
2
Как использовать секрет клиента? Можете ли вы вместо этого создать ключ API с учетной записью службы?
Стивен Филлипс,
42

Я знаю, что сейчас немного поздно отвечать, но для других людей, которые борются с той же проблемой.
Просто измените разрешение листа на общедоступное на вашем диске, чтобы к нему можно было получить доступ без аутентификации через вызовы API.

Чтобы изменить доступ:

  1. Открыть лист на Google Диске
  2. В правом верхнем углу нажмите Поделиться
  3. В нижней части окна подсказки нажмите Дополнительно
  4. Измените разрешение на общедоступное или людей со ссылкой (вход не требуется)

Отправить запрос API для извлечения данных из таблиц без аутентификации.

Примечание: если лист содержит конфиденциальные данные, то делать его общедоступным небезопасно, а лучше делать это с доступом с проверкой подлинности.

WLatif
источник
36
Кроме того, вы можете поделиться этим листом с конкретным адресом электронной почты Ex. адрес электронной почты вашего служебного аккаунта (проекта). "client_email": "XXXXX@niversity-gasket-XXXX.iam.gserviceaccount.com", это позволит получить доступ к листу с помощью вашего скрипта.
Кишан Патель
4
Спасибо, бро. В документации нет ничего написанного, как вы упомянули.
Maulik Dodia
1
Согласен @MaulikDodia. Документы Google API говорят об этом здесь , но это непонятно для людей, которые просто хотят использовать API для отображения данных на общедоступном веб-сайте. Я сейчас пишу инструкции по всему этому. Я пришлю тебе DM, когда закончу.
Эдвард
Большое спасибо, друг @ user3411192
Маулик Додиа
27

Обязательно обратите внимание на комментарий @ KishanPatel:

Кроме того, вы можете поделиться этим листом с конкретным адресом электронной почты Ex. адрес электронной почты вашего служебного аккаунта (проекта). "client_email": "XXXXX@niversity-gasket-XXXX.iam.gserviceaccount.com", это позволит получить доступ к листу с помощью вашего скрипта.

Хорен
источник
4

Самый простой способ - исправить с помощью gcloud cli. Больше документов здесь https://cloud.google.com/pubsub/docs/quickstart-cli#before-you-begin

установить gcloud

sudo apt-get install google-cloud-sdk

тогда позвони

gcloud init

затем проверьте свой активный проект и учетные данные

gcloud config configurations list

Если это не так, убедитесь, что вы прошли аутентификацию с правильной учетной записью:

gcloud auth list
* account 1
  account 2

Если нет, перейдите в аккаунт проекта:

gcloud config set account `ACCOUNT`

В зависимости от аккаунта список проектов будет разным:

gcloud projects list

- project 1
- project 2...

Перейти к предполагаемому проекту:

gcloud config set project `PROJECT NAME`

Затем создайте учетные данные приложения по умолчанию с помощью gcloud auth application-default login, а затем google-cloud автоматически обнаружит такие учетные данные.

Юлия Ашомок
источник
0

Мои 10 центов ... Простой пример чтения листа с помощью Java .

    private Credential getCredentials() throws IOException {
            final InputStream accessKey = new ByteArrayInputStream("<credential json>");
            final GoogleCredential credential = GoogleCredential.fromStream(accessKey)
                    .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS_READONLY));
            return credential;
        }

    private HttpTransport httpTransport() {
            try {
                return GoogleNetHttpTransport.newTrustedTransport();
            } catch (GeneralSecurityException | IOException e) {
                throw new SpreadSheetServiceException(e);
            }
        }


    Sheets service = new Sheets.Builder(httpTransport(), JSON_FACTORY, getCredentials())
                    .setApplicationName("app-name")
                    .build();
            ValueRange response = service.spreadsheets().values()
                    .get("<spread_sheet_id>", "A1:A")
                    .execute();
Пальма Диас
источник