17

我遇到了一个棘手的问题。

我正在使用 Appengine Endpoints 来实现我的服务器端 API。此 API 将一些数据返回给我的用户。应用程序产品购买中的应用程序支持。我的想法很简单:一旦用户购买了某个产品,API 就会返回额外的数据。直接的方法是将标志作为参数传递给 API。但我想通过对我的端点启用 OAuth 身份验证来使其更安全。因此,一旦用户购买了某些东西,它就会在服务器上得到验证和记忆。因此,我的 API 端点将始终知道将哪些数据返回给特定用户。

然而问题如下。我不想强迫用户进行身份验证,除非他们想购买。但是有一种情况,用户可能会使用另一台设备,而不是通过我的应用程序使用他们的谷歌帐户登录。这样我的 API 将只返回免费数据,但用户购买了付费产品。我可以通过播放服务查询购买的产品,但我仍然需要在我的服务器上进行身份验证或传递一个标志来获取完整数据。

这些事情通常是怎么做的?我可以默默地使用用户的第一个 Google 帐户(afaik 保证在 Play Store 上使用)在我的服务器上进行身份验证,还是这是错误的?

谢谢。

4

1 回答 1

7

您应该为您提到的内容使用OAuth 2.0 。

您可以使用第一个允许在您的服务端进行身份验证的 Google 帐户。OAuth 2.0 是一个很棒的工具,它可以简化并让开发人员轻松地允许用户访问您的应用程序,可能是游戏或交易平台。OAuthHmacSigner 对象将在初始化时为您管理身份验证:

signer = new OAuthHmacSigner();
signer.clientSharedSecret = Constants.CONSUMER_SECRET;

然后 Android 活动使用以下代码启动OAuth流程:

launchOauth.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        startActivity(new Intent().setClass(v.getContext(),
                PrepareRequestTokenActivity.class));
    }
});

要为您的应用程序实现它,您可以使用 Java 集成 OAuth 2.0 Google OpenID,但您也可以选择使用 Python 或 Ruby。它提供了多种工具来提高安全性,从而也可以轻松构建防伪状态令牌:

String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
return new Scanner(new File("index.html"), "UTF-8")
  .useDelimiter("\\A").next()
  .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
  .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
  .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
              APPLICATION_NAME);

为了获得 OAuth 2.0 访问令牌,您只需调用:

AccountManager.getAuthToken() 

它使用 oauth2 的 authTokenType 请求令牌。然后,您可以像往常一样将其集成到托管在服务器端的后端。

于 2014-03-20T05:30:03.773 回答