我是一名Android开发人员,为我的应用构建了我的第一个Google App Engine(java)后端.除了我的应用程序之外,我不希望任何其他人访问此API.(我计划在我的Android应用程序中使用App引擎验证InApp购买).我的数据与用户无关,因此我不希望用户即使使用他们的Google帐户(在网络或Android设备上)登录也能访问我的API.
我按照"在API后端中指定授权客户端"(https://developers.google.com/appengine/docs/java/endpoints/auth)中提到的步骤进行操作,例如生成客户端ID并将其添加到@Api(clientIds和观众)除了"添加用户参数" - 因为我不需要用户身份验证.
然后我部署了App引擎,我仍然可以通过API资源管理器访问API(https://your_app_id.appspot.com/_ah/api/explorer)(我还没有添加API_EXPLORER客户端ID)
我在添加客户端ID之前使用使用端点库构建的APK进行了测试,并且仍然可以访问API.
是否必须向所有端点API添加"用户参数"?实现我的目的(限制API到我的Android应用程序).
我可以从Android客户端传递null作为userAccount名称并忽略服务器上的用户参数值(因为它将为null)?这是否确保API只能从我的Android应用程序访问(因为客户端ID是为我的包名和APK的SHA1生成的?)
我应该为此目的使用类似服务帐户的东西吗?
文档说,对于Android,必须添加Android和Web客户端ID,并且受众必须与Web客户端ID相同.这是否可以访问任何其他Web客户端?我可以跳过提及Web客户端ID并仍然达到我的目的吗?
感谢您的时间和帮助.
......随着我的进一步调查而更新......
我做了以下事情:
在后端的API中添加了User参数 - 但没有检查空值.无需传递任何凭据即可访问API(来自Android调试APK和API资源管理器)
然后,我试过了
mCredential = GoogleAccountCredential.usingAudience(this,"server:client_id:"+ WEB_CLIENT_ID); mCredential.setSelectedAccountName(NULL);
并将此凭据传递给API构建器(如其他一些帖子中所建议的)导致致命异常.所以,我们不能传递null帐户名.
我可以在没有OAuth的情况下使用API资源管理器调用API.但是当我启用OAuth时,它提示错误,说不允许此客户端ID!(我还没有在client_ids {}中添加com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID)
然后我添加了代码,如果用户为null,则在后端抛出OAuthRequestException.这导致API资源管理器在没有OAuth的情况下收到错误.将API_EXPLORER_CLIENT_ID添加到client_ids后,它可以启用OAuth
添加了从我的Android应用程序传递有效用户帐户名(电子邮件)的代码.然后,我只能使用我的发布APK访问API.即使是调试APK也会有异常! - 这是我的预期.所以,我认为没有其他Android应用程序能够访问此API.
因此,不检查后端API上的null用户是个坏主意(如其他帖子所示).它没有提到任何client_ids而没有User param.
我现在唯一的问题是:如果有人可以从APK中找出WEB_CLIENT_ID,他们是否可以使用它来构建一个Web客户端来访问我的API(我没有在代码中的任何地方提到过客户端秘密.所以我认为这是不可能的).
我确实搜索了Google群组和Stackoverflow,但目前尚不清楚.
(将我的"应用" 验证到Google云端点而不是"用户")将 我的"应用"验证为Google Cloud Endpoints而不是"用户"
(如何保护使用Google Cloud Endpoints构建的API?) 如何保护使用Google Cloud Endpoints构建的API?
(限制访问谷歌云端点到Android应用) 限制访问谷歌云端点到Android应用程序
我的Android应用程序需要加密文件,以便以后可以解密和读取.除了应用程序,甚至用户之外,其他任何人都无法解密.
以下是我如何进行加密和解密.这在大多数情况下都有效,但有些用户有时会失败.它不是特定的手机(Nexus7,三星,摩托罗拉,HTC - 所有类型都报告此问题),但并非所有用户都遇到它.偶尔只有一些用户.
这是相关代码:
encrypt() {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
final KeyStore.PrivateKeyEntry entry;
if (!ks.containsAlias(CERT_ALIAS)) {
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.YEAR, 50);
Date end = cal.getTime();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext())
.setAlias(CERT_ALIAS)
.setStartDate(now)
.setEndDate(end)
.setSerialNumber(BigInteger.valueOf(1))
.setSubject(new X500Principal("CN=" + CERT_ALIAS))
.build());
KeyPair kp = kpg.generateKeyPair();
}
entry = (KeyStore.PrivateKeyEntry) ks.getEntry(
CERT_ALIAS, null);
pub = entry.getCertificate().getPublicKey();
// use the pub key to encrypt
}
decrypt() {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
final KeyStore.PrivateKeyEntry entry = …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序内托管项目(非订阅),我将其记录在我的服务器上后(在使用购买状态API进行验证后)使用它.我了解,应用内购买的退款/取消只能通过Merchant帐户控制台完成.Android应用是否会收到有关已消费商品的取消/退款的通知?
queryInventoryAsync()消费后,API不会返回任何项目.应用是否需要定期继续调用此API以了解取消/退款?
我测试了购买状态API(在服务器上)在取消后返回信息.
INFO: {
"consumptionState" : 1,
"developerPayload" : "payload",
"kind" : "androidpublisher#inappPurchase",
"purchaseState" : 1,
"purchaseTime" : "1392878938499"
}
Run Code Online (Sandbox Code Playgroud)
在我使用它之后,我认为订单信息已在Google Play服务器上清除.如果是这样,我不能依赖购买状态API来检测取消.
旁注:但是我注意到通过购买状态API返回的consumptionState不正确.我已经使用它了,queryInventoryAsync()不再在设备上返回此项.一段时间后,purchaseState从"0"变为"1"(取消),但consumptionState仍为1 - 尚未消耗.我希望它可以正常购买(我还在测试模式)
在文档中,只有v2 API有一些关于取消/退款的信息(IN_APP_NOTIFY intent).V3 InApp billing API不讨论处理退款/取消.TrivialDrive示例也没有任何示例.
我查看了这些问题但还不清楚.
Android应用内结算:订单取消后,购买状态保持"已购买" Android应用内结算:订单取消后,购买状态保持"已购买"状态