#google-apps-script #oauth-2.0
#google-apps-script #oauth-2.0
Вопрос:
Я успешно настроил подключение из Google Apps script к базе данных Google Cloud firestore с помощью учетной записи сервиса. Он работает нормально, пока я сохраняю учетные данные в самом файле скрипта приложений. Если я сохраняю закрытый ключ учетных данных где-то еще (в базе данных, в файле диска, документе Google …), проверка подлинности oauth2 завершается ошибкой: «Недопустимый аргумент: ключ», выданный библиотекой GAS Oauth2.
Я исследовал дальше, и, похоже, это проблема с кодировкой / кодировкой символов. Если я сравниваю длину строки закрытого ключа между жестко закодированным и сохраненным в файле / БД, длина ключа не равна, но ключевые строки кажутся идентичными.
Была бы признательна за некоторую помощь.
function createOAuth() {
// credentials of service account hard coded
var jsonObj = {
"type": "service_account",
"project_id": "id of project",
"private_key": "-----BEGIN PRIVATE KEY-----.....----END PRIVATE KEY-n",
"client_email": "servic accoutn email",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
}
// not working if store attribute private_key somewhere else like:
/*var fileContent = DriveApp.getFileById('idOfFile').getBlob().getDataAsString("UTF-8"); //OR
DocumentApp.getBody().getText() //OR
var privateKey = Utilities.newBlob(privatKeyFromCredents).getDataAsString()
//store key in cloud firestore database also not working.
*/
return OAuth2.createService("Service Account")
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(jsonObj.private_key)
.setIssuer(jsonObj.client_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setCache(CacheService.getScriptCache())
.setParam('access_type', 'offline')
.setScope('https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/datastore');
var access = service.hasAccess(); // true if jsonObj is hard coded
// false if stored somewhere else --> error: Invalid Argument: Key
Logger.log('Access: ' access);
}
Комментарии:
1. Как насчет сохранения его в текстовом файле или файле bin?
2. Что касается прокомментированного скрипта, если файл
idOfFile
является текстовым файлом, а содержимое файлаidOfFile
является-----BEGIN PRIVATE KEY-----.....----END PRIVATE KEY-n
, например, как насчетvar privateKey = DriveApp.getFileById('idOfFile').getBlob().getDataAsString();
? Кстати, чтоprivatKeyFromCredents
в вашем скрипте?3. Я также пробовал сохранять ключ в текстовых файлах (в различных форматах). но это также не сработало. следующий код был еще одной попыткой преобразовать ключ, который был сохранен в текстовом файле на диске, создать большой двоичный объект и преобразовать ключ в другую кодировку: var PrivateKey = Utilities.newBlob(privatKeyFromCredents).getDataAsString() но это также не удалось…
4. Мне интересно, в каком формате жестко закодированная строка хранится в файле скрипта приложений? поскольку длина строки ключа отличается, если проверить длину переменной, в которой хранится жестко закодированный ключ, по сравнению с чтением ключа в формате utf-8 из google doc или текстового файла…
5. @Jochen Спасибо за ответ. Сначала я прошу прощения, что мой комментарий не был полезен для вашей ситуации. В качестве следующего метода, например, как насчет прямой загрузки загруженного файла при создании учетной записи службы на Google Диск и его использования? Файл является файлом json. Таким образом, закрытый ключ может быть восстановлен. Могу я спросить вас об этом?
Ответ №1:
// get Credentials form Drive in JSON format
var fileContent = DriveApp.getFileById('18t9NnzwKMlmQAnRUa_KovWdDvhk60oZT').getBlob().getDataAsString("UTF-8");
var serviceCredentials = JSON.parse(fileContent);
serviceCredentials['service_name'] = "Service Account Name";
serviceCredentials['scope'] = "https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/datastore ";
var service = OAuth2.createService(serviceCredentials.service_name)
.setTokenUrl(serviceCredentials.token_uri)
.setPrivateKey(serviceCredentials.private_key)
.setIssuer(serviceCredentials.client_email)
.setPropertyStore(PropertiesService.getUserProperties())
.setCache(CacheService.getUserCache())
.setParam('access_type', 'offline')
.setScope(serviceCredentials.scope);
// for testing if access oauth setup is working or not
var access = service.hasAccess();
Logger.log('Access: ' access); //true or false
Комментарии:
1. Ответы только с кодом не совсем хороши. Вы должны предоставить некоторый пояснительный текст, в котором кратко описывается, почему ваш ответ работает.