【发布时间】:2016-03-14 11:25:28
【问题描述】:
我正在创建我的第一个应用引擎应用,但在验证用户时遇到了问题。
我已经关注https://cloud.google.com/appengine/docs/python/endpoints/consume_android#making_authenticated_calls - 似乎有点神奇,我只是“setAccountName”并且它应该可以工作,但是我想它应该从 Android Audience 加载应用程序范围,然后检查如果我传递的帐户名实际上已经登录了设备。
API 调用有效,通过了身份验证,但遗憾的是 - 后端的“endpoints.get_current_user()”函数返回 None。
所以我一直在挖掘,但我似乎找不到任何关于这个主题的东西。我发现的最好的东西是http://blog.notdot.net/2010/05/Authenticating-against-App-Engine-from-an-Android-app - 但那是 6 年前的一篇文章,作者使用 HTTP 客户端,与端点库无关。
我所能想到的就是遵循一些“非端点”方式将“使用 Google 登录”添加到我的应用程序中,然后尝试将我将获得的凭据传递给我的 API 构建器,但这感觉不对,应该有更简单的方法来做到这一点。
那么,我是否遗漏了https://cloud.google.com/appengine/docs/python/endpoints/consume_android#making_authenticated_calls 中未提及的某些步骤?
实际代码(略简化)如下:
后端:
auth_api = endpoints.api(
name='auth_api',
version='v1.0',
auth_level=endpoints.AUTH_LEVEL.REQUIRED,
allowed_client_ids=[
ANDROID_CLIENT_ID,
WEB_CLIENT_ID,
endpoints.API_EXPLORER_CLIENT_ID,
],
audiences=[
WEB_CLIENT_ID,
endpoints.API_EXPLORER_CLIENT_ID,
],
scopes=[
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email',
],
)
@auth_api.api_class(resource_name='rating')
class RatingHandler(remote.Service):
@endpoints.method(
message_types.VoidMessage,
RatingsMessage,
path='rating/getRatings',
http_method='GET',
)
def getRatings(self, request):
rating_query = Rating.query(
ancestor=ndb.Key(
Account,
endpoints.get_current_user().user_id(), // ERROR! endpoints.get_current_user() is None
)
).order(-Rating.rating)
客户:
// Somewhere these lines exist
if (credential == null || credential.getSelectedAccountName() == null) {
startActivityForResult(
AuthUtils.getCredentials(getActivity()).newChooseAccountIntent(),
AuthUtils.REQUEST_ACCOUNT_PICKER
);
} else {
LoadRatings();
}
@Override
public void onActivityResult(
int requestCode,
int resultCode,
Intent data
) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && data.getExtras() != null) {
String accountName =
data.getExtras().getString(
AccountManager.KEY_ACCOUNT_NAME
);
if (accountName != null) {
credential = GoogleAccountCredential.usingAudience(
getApplicationContext(),
"server:client_id:" + Constants.ANDROID_AUDIENCE
);
credential.setSelectedAccountName(accountName);
LoadRatings();
}
}
}
public void LoadRatings() {
// AuthApi was auto-generated by Google App Engine based on my Backend
AuthApi.Builder api = new AuthApi.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(),
credential
).setApplicationName(getPackageName());
AuthApi service = api.build();
try {
ApiMessagesRatingRatedBeerListMessage result = service.rating().getRatings().
// some stuff done with result, but the Exception is thrown in line above
【问题讨论】:
-
您是在尝试使用 Google+ 帐户对用户进行身份验证,还是尝试进行其他身份验证?
-
我想要的只是使用 Google 帐户对用户进行身份验证,并在后端提供可用的电子邮件地址。我让帐户选择器工作并设置帐户名称,就像cloud.google.com/appengine/docs/python/endpoints/… 描述的那样。 API 调用有效,但我的目标是后端没有可用的用户对象
-
@saiyr 我没有(我刚刚编辑了问题以包含 api 声明)。另外,如果我忘记添加客户端身份验证,我很确定请求会在不执行 API 代码的情况下被拒绝,因此不会引发错误
标签: android google-app-engine authentication google-cloud-endpoints