使用 Cloud Endpoints 获取用户信息(使用其他 API Endpoints)

Getting user info with Cloud Endpoints (using other API Endpoints)

我正在尝试设置端点 api(使用 google 应用引擎,python),但我在获取用户配置文件信息时遇到了一些问题。 API 正在运行,我可以通过本地主机上的 API Explorer 创建实体。

我的目标是允许用户通过仅提供电子邮件并授权该应用从他们的个人资料中获取信息的重置来注册我的应用。我有这个端点方法:

@User.method(http_method="POST",
             auth_level=endpoints.AUTH_LEVEL.REQUIRED,
             allowed_client_ids=[
               endpoints.API_EXPLORER_CLIENT_ID
             ],
             scopes=[
               'https://www.googleapis.com/auth/userinfo.email',
               'https://www.googleapis.com/auth/userinfo.profile',
               'https://www.googleapis.com/auth/plus.me',
             ],
             user_required=True,
             request_fields=('email',),
             response_fields=('id',),
             name="register",
             path="users")
def UserRegister(self, instance):
    logging.info(os.getenv( 'HTTP_AUTHORIZATION' ))
    # 'Beared __TOKEN__'
    logging.info(endpoints.users_id_token._get_token(None))
    # '__TOKEN__'
    instance.put()
    return instance

这很好用,我收到了授权令牌,并且在数据存储中创建了用户,但我不知道如何获取个人资料信息。如果我在 OAuth2 API(通过 API Explorer)中输入令牌:

POST https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=__TOKEN__

我得到令牌信息和我需要的一些数据 { "user_id": "__ID__", "verified_email": true, ...},如果我在 +API:

中使用 user_id
GET https://www.googleapis.com/plus/v1/people/__ID__

我可以获得我需要的其余数据(名称、图像等)。

我需要做什么才能在我的 UserRegister() 方法中实现这一目标?我更喜欢 return 只是实体 ID 并异步完成其余的注册,但这是另一个问题,我会弄清楚的(;只需要一些指导如何从我的代码调用其他端点...

编辑:

我已经设法弄清楚如何调用其他 APIs (code on Gist),现在只有一个问题与 Plus API:

我做了一些查询,最终得到 匿名配额错误。然后我添加了 key 参数并将其设置为 WEB_CLIENT_IDSERVICE_ACCOUNT:

现在我收到以下错误:

HttpError: <HttpError 400 when requesting https://www.googleapis.com/plus/v1/people/__VALID_USER_ID__?key=__WEB_CLIENT_ID__or__SERVICE_ACCOUNT__&alt=json returned "Bad Request">

当我使用 +API explorer 时,我得到了预期的结果:

REQUEST:

https://www.googleapis.com/plus/v1/people/__VALID_USER_ID__?key={YOUR_API_KEY}

RESPONSE:

200 OK + json data for user...

有人知道为什么会这样吗?

为什么我会收到 BadRequest 响应?

BadRequest 的问题是我没有发送授权令牌...我确实尝试将其作为 access_token 发送,但是像 +api docs 这样的接缝已经过时了 - 它应该是 oauth_token。当我包含此参数时,问题已解决:

build('plus', 'v1').people().get(userId=user_id, key=SERVICE_ACCOUNT, oauth_token=token).execute()

提示:使用http://localhost:8001/_ah/api/discovery/v1/apis/,而discoveryRestUrl属性必须看到真实 API 的属性 - 这是我找到答案的地方。

oauth_token可以这样得到:

token = os.getenv('HTTP_AUTHORIZATION').split(" ")[1]
# or like in my question:
token = endpoints.users_id_token._get_token(None)

我建议使用 HTTP_AUTHORIZATION 变量,因为 users_id_token 文档指出它是:

Utility library for reading user information from an id_token.

This is an experimental library that can temporarily be used to extract a user from an id_token. The functionality provided by this library will be provided elsewhere in the future.

如何调用其他 API 端点?

这也是我第一个问题的答案:

from googleapiclient.discovery import build

service = build('plus', 'v1')
request = service.people().get(userId=user_id, key=SERVICE_ACCOUNT, oauth_token=token)
response = request.execute()

data = dict(self.response.POST)

对我有用的代码是 here

注意: WEB_CLIENT_IDhttps://console.developers.google.com/apis/credentials 获得(Web 应用程序类型的 OAuth2 客户端 ID)将 NOT 在这种情况下有效。我不得不使用 SERVICE_ACCOUNT - 我没有尝试通过控制台生成一个,我从 App Engine 获得的默认服务帐户工作正常。

...现在我开始工作了,事情就清楚多了。希望它能帮助别人 (;