Авторизация с помощью сервисного аккаунта
Рекомендуется для связи Сервер → Сервер
Пройдите первоначальную настройку проекта
Инструкция по первоначальной настройке проекта находится в разделе "Добавление проекта и приложения".
Убедитесь, что все шаги успешно пройдены и приложение прошло модерацию.
Добавьте сервисный аккаунт
В проекте на вкладке "API и сервисы / Сервисные аккаунты" создайте новый аккаунт. По сути это отдельный пользователь Garpun, который имеет доступ к аккаунту вашей организации с максимальными правами, его действия будут логироваться как действия обычного пользователя.
Добавьте ключ доступа к сервисному аккаунту
После создания сервисного аккаунта вы попадаете на его карточку, там вы должны выпустить api-ключ.
Сохраните его в защищенном месте, так как если вы его потеряете — то с его помощью злоумышленники смогу получить доступ к вашему приложению.
Если это произошло — удалите ключ и доступ будет отозван в течение некоторго непродолжительного времени.
Вы можете добавить несколько ключей для вашего приложения, если это необходимо например для разных подсистем.
Получение токена
Чтобы работать с API нужно сгенерировать jwt токен с помощью сервисного аккаунта и обменять его на access_token для доступа в апи.
В этом случае у вас не будет refresh_token. Работает так (RFC5723 (opens in a new tab)):
- вы генеририруете jwt_assertion токен у себя
- отправляете его на сервер account.garpun.com
- сервер проверяет jwt подпись и выдает вам access_token
Вы можете реализовать это вручную или с использованием Google Auth Lib. На текущий момент проверна работосполобность следующих способ для Java и Python
Генерация с помошью Google Auth Lib Java
google-auth-library-java (opens in a new tab)
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;
import java.util.Collections;
public class Main {
public static void main(String[] args) throws Exception {
String credFilename = "../creds.json";
GoogleCredentials credentials = GoogleCredentials.fromStream(
new FileInputStream(credFilename)
);
if (credentials.createScopedRequired()) {
credentials = credentials.createScoped(Collections.singletonList("account-management"));
}
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
System.out.println("token = " + token);
}
}
Генерация с помошью Google Auth Lib Python
google-auth-library-python (opens in a new tab)
Рекомендуемая версия google-auth==2.30.0 или выше.
from google.auth.transport.requests import Request
from google.oauth2 import service_account
from google.oauth2.service_account import Credentials
credFileName = "../creds.json"
credentials: Credentials = service_account.Credentials.from_service_account_file(
credFileName,
scopes=['account-management', 'userinfo.profile', 'cloud-platform'],
)
credentials = credentials.with_claims({"aud": "https://account.garpun.com/oauth2/token"})
credentials.refresh(Request())
print("credentials.token = %s" % str(credentials.token))
Генерация вручную на Python
Предварительно устанавливаем необходимые библиотеки
requirements
requests
PyJWT==1.7.1
cryptography==42.0.7
Установка библиотек
pip install requests PyJWT==1.7.1 cryptography==42.0.7
Получение токена
import json
import time
import jwt
import requests
# Задаем путь к файлу c creds
creds_filepath = 'creds.json'
# Считываем доступы к dict
with open(creds_filepath, 'r') as f:
sa = json.loads(f.read())
# Готовим данные для JWT
issuer_ = sa['client_email']
key_id = sa['private_key_id']
private_key = sa['private_key']
now = int(time.time())
payload = {
'aud': sa['token_uri'],
'iss': issuer_,
'iat': now,
'exp': now + 360,
}
# Формирование JWT
encoded_token = jwt.encode(
payload,
private_key,
algorithm='RS256',
# передача kid ОБЯЗАТЕЛЬНА!
headers={'kid': key_id},
)
# Получаем access token по подписанному вам jwt
token_url_ = payload['aud']
resp = requests.post(token_url_, data={
"assertion": encoded_token,
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
})
print("resp.status_code = %s" % str(resp.status_code))
if resp.ok:
token_info = resp.json()
print("access_token = %s" % str(token_info['access_token']))
print("token_info = %s" % str(token_info))
else:
print("resp.text = %s" % str(resp.text))
Локальное использование
Если возникла необходимость протестировать работу ключа сервисного аккаунта налокально запущеной Мете, необходимо учесть, что локальная Мета ожидает в качестве параметра aud ссылку на локальную же Мету (http://localhost:8080/oauth2/token (opens in a new tab)), поэтому работать будет только ручной способ генерации JWT токена, который позволяет подставить нужный aud.