基于Java的Google App Engine,Android和身份验证oauth2

时间:2014-07-18 14:51:55

标签: android google-app-engine authentication

身份验证和应用引擎,有很多东西需要阅读,但很多似乎已经过时了!

即使是谷歌页面https://developers.google.com/appengine/docs/java/endpoints/consume_android#making-authenticated-calls

在这里,他们谈论'GoogleAccountCredential.usingAudience',但现在,你应该使用GoogleAuthUtil(据我所知,如果我错了请纠正我。)

我正在尝试将应用引擎设置为我的Android应用(以及将来的iOS应用)的后端。

我正在使用Android Studio,使用“新模块”并选择了带有云消息的应用引擎。

我创建了一个简单的端点,并在那里有一个函数,这里有一些代码:

public class ReviewEndpoint {

// Make sure to add this endpoint to your web.xml file if this is a web application.

private static final Logger LOG = Logger.getLogger(ReviewEndpoint.class.getName());

/**
 * This method gets the <code>Review</code> object associated with the specified         <code>id</code>.
 * @param id The id of the object to be returned.
 * @return The <code>Review</code> associated with <code>id</code>.
 */
@ApiMethod(name = "getReview")
public Review getReview(@Named("id") Long id) {
    // Implement this function
    Review r = new Review();
    r.setData("test!");

正如您所看到的,这是由Android Studio很好地生成的。我实现了一些stuf,比如创建'review'对象并在最后返回它。

在Android方面,我可以这样做:

ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null);
ReviewEndpoint ep = b.build();
Review review = ep.getReview(1L).execute();
data = review.getData();

是的,我得到'测试!' :)

现在,我希望对此进行身份验证。我想知道哪个用户写了什么,所以我想我以后会使用GMail帐户和Facebook。

我在这里被困住了。我可以在Android上从用户那里获得令牌:

token = GoogleAuthUtil.getToken(MainScreenActivity.this, mAccount.name, "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile");

然后您可以将此令牌作为凭证添加到请求中:

Credential cr = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token);
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), cr);

然后在app引擎中我尝试获取用户信息,但是如何? 它会作为“持票人”提供吗?我如何获得此持票人令牌?我是否应该执行API请求以获取服务器上的数据?

这不起作用:

OAuthService service = OAuthServiceFactory.getOAuthService();
try {
    User user = service.getCurrentUser();

谁能给我一个抬头?

1 个答案:

答案 0 :(得分:5)

所以最后,今天,我发现了如何做到这一点!之前我在Stackoverflow上有过这方面的问题而且从来没有得到答案,但这些网站给了我答案:

https://developers.google.com/appengine/docs/java/endpoints/auth

https://developers.google.com/appengine/docs/java/endpoints/consume_android

第一个显示了在应用引擎方面需要完成的工作。第二页将告诉您如何获取凭据。我很亲密。我不确定是否需要调整第二个链接中提到的build.gradle文件。我添加到App Engine的内容:

@Api(name = "reviewEndpoint", version = "v1", ...<<some more stuff here >>
    scopes = {Constants.EMAIL_SCOPE},
    clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID},
    audiences = {Constants.ANDROID_AUDIENCE})

然后获取凭据:

// Initialize the scope using the client ID you got from the Console.
final String scope = "server:client_id:" + Constants.WEB_CLIENT_ID;

credential = GoogleAccountCredential.usingAudience(activity,scope);

您必须添加用户的电子邮件地址:

credential.setSelectedAccountName("some-mail-address@gmail.com");

您可以使用帐户选择器获取电子邮件地址(也可以在您点击链接时显示示例)

然后。你使用凭证调用端点,我认为Play服务将验证用户,因为如果我使用未登录设备的电子邮件,它将无法正常工作。以下代码将抛出GoogleAuthIOException:

ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(
    AndroidHttp.newCompatibleTransport(), 
    new AndroidJsonFactory(), id_token);
ReviewEndpoint ep = b.build();
Review review;
review = ep.getReview(1L).execute();

进行测试,我把我在服务器端得到的电子邮件地址作为查询对象中的一个字符串,然后它给了我电子邮件地址而不是用户对象为空。噢!我忘了告诉你,你需要在app引擎端有用户参数。即使您在上面的'getReview'调用中没有看到'user'参数,它也会被App Engine添加。

这就是我的getReview现在的样子:

@ApiMethod(name = "getReview")
public Review getReview(@Named("id") Long id, User user) {
    // Implement this function
    Review r = new Review();

    r.setData("user == " + (user == null ? "NULL " : user.toString()));

希望这会有所帮助