Google App Engine — API конечных точек — Использование из другого приложения App Engine — python

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

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

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

Вот код, который работает на вызывающей стороне:

f = file('key2.pem', 'rb')
key = f.read()
f.close()

credentials = SignedJwtAssertionCredentials(
     'my-service-account-email-from-caller-app@developer.gserviceaccount.com',
      key,
      scope='https://my-app-id.appspot.com/_ah/api/my-api/v1')
http = credentials.authorize(httplib2.Http())
service = build("my-api", "v1", http=http)

Когда я запускаю этот код, я получаю сообщение об ошибке: AccessTokenRefreshError: invalid_grant

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

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

Кто-нибудь смог вызвать функцию API конечной точки в одном приложении движка приложения с другим приложением движка приложения, используя oauth2?

Заранее спасибо, -мат


person user3292469    schedule 10.02.2014    source источник
comment
Вы находитесь на неизведанной территории. Конечные точки в том виде, в каком они существуют в настоящее время, предназначены для связи между клиентом и сервером, когда клиент управляется пользователем.   -  person Dan Holevoet    schedule 12.02.2014
comment
Вам когда-нибудь везло с этим? Я пытаюсь сделать то же самое сейчас, но только из скрипта Python, работающего на моем локальном компьютере. Мне очень трудно получить мой запрос API для авторизации.   -  person TedCap    schedule 13.09.2014


Ответы (1)


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

объем:

Я передаю https://www.googleapis.com/auth/userinfo.email для области действия класса SignedJwtAssertionCredentials. Учитывая сообщение об ошибке, которое вы видите, это, вероятно, причина. Я считаю, что объем электронной почты требуется как минимум, исходя из этой документации< /а>.

Службы моих конечных точек, которые я вызываю, также указывают allowed_client_ids, чтобы ограничить доступ к списку известных клиентов, одним из которых является учетная запись службы, которую я предоставил для связи с этими конечными точками.

URL-адрес службы обнаружения:

Я передаю параметр DiscoverServiceUrl в функцию build(). Учитывая ваше сообщение об ошибке, это маловероятно, но решил упомянуть об этом.

----РЕДАКТИРОВАТЬ----

Добавление примера кода по запросу ниже.

Для проекта консоли Google с id=1234567890 это код клиента, который я использую для вызова конечной точки службы:

from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials

service_account_email = '[email protected]'
key_file_path = os.path.join(config.base_path, 'myservice.pem')

key_file = file(key_file_path, 'rb')
key = key_file.read()
key_file.close()

credential = SignedJwtAssertionCredentials(service_account_email, key, 'https://www.googleapis.com/auth/userinfo.email')
http = credential.authorize(httplib2.Http())

discoveryServiceUrl = 'http://mysite.appspot.com/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest'
myservice = build('myservice', 'v1', http=http, discoveryServiceUrl=discoveryServiceUrl)

И это объявление службы с параметром allowed_client_ids, указывающим мой проект API Google (id: 1234567890)

@myservice_api.api_class(resource_name='myservice', path='myservice', allowed_client_ids=['1234567890.apps.googleusercontent.com', '1234567890-aasgqg243rsaggw4.apps.googleusercontent.com', endpoints.API_EXPLORER_CLIENT_ID])
class MyService(remote.Service):
    ...

Надеюсь это поможет.

person Brian Weller    schedule 14.02.2014
comment
Привет, Брайан, у тебя есть пример кода или суть, которой ты можешь поделиться? Я бился головой о стену, пытаясь заставить это работать. - person TedCap; 13.09.2014
comment
Привет, TedCap, я обновил свой ответ образцом кода как для кода вызова клиента, так и для объявления службы... дайте мне знать, если это работает или вам нужны какие-либо разъяснения. - person Brian Weller; 15.09.2014
comment
Брайан Веллер, ты мой герой недели. Серьезно, огромное вам спасибо. Это было все, что мне было нужно. У меня наконец-то заработало! Этот отсутствующий идентификатор проекта был ключом к использованию метода build() с пользовательским API. - person TedCap; 16.09.2014
comment
Нет проблем... рад, что смог помочь. :-) - person Brian Weller; 16.09.2014