我想限制我的API端点仅访问我的Android应用,但没有google_account /密码。 我选择了这些方法:https://developers.google.com/accounts/docs/OAuth2
为了测试,我成功使用此方法将我的Android应用程序验证到我的API:https://cloud.google.com/appengine/docs/python/endpoints/consume_android ==>此方法允许您使用组合验证您的应用程序:
因此,如果有人获取我的代码(反编译apk)并修改我的Android代码,他们就无法访问我的API,因为我的应用程序的SHA1指纹会发生变化。 (我测试了它,它的工作原理=)) 此方法运行正常,但我不希望Google登录/密码进行身份验证..
所以我尝试了这种方法:https://developers.google.com/accounts/docs/OAuth2ServiceAccount 我成功验证了我的Android应用程序,但是,如果我的android代码被其他人修改(所以SHA1已更改),我的Android应用程序仍然可以连接到我的API!因此,如果有人获得我的包并对其进行反编译,他将自由更改代码并成功访问我的API ..
这是我的API代码:
@ApiMethod( name = "ListCampagnes", httpMethod = ApiMethod.HttpMethod.GET, path="list", clientIds = {CONSTANTES.ANDROID_CLIENT_ID, CONSTANTES.WEB_CLIENT_ID, CONSTANTES.SERVICE_CLIENT_ID, com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID}, audiences = {CONSTANTES.ANDROID_AUDIENCE})
public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws UnauthorizedException {
if (user == null) throw new UnauthorizedException("User is Not Valid");
return CampagneCRUD.getInstance().findCampagne(NumPortable);
}
这是我的android代码:
GoogleCredential credentialToAppengine;
try {
String p12Password = "notasecret";
KeyStore keystore = KeyStore.getInstance("PKCS12");
InputStream keyFileStream = getAssets().open("59ce5a08e110.p12");
keystore.load(keyFileStream, p12Password.toCharArray());
PrivateKey key = (PrivateKey)keystore.getKey("privatekey", p12Password.toCharArray());
credentialToAppengine = new GoogleCredential.Builder().setTransport(AndroidHttp.newCompatibleTransport()).setJsonFactory(new JacksonFactory()).setServiceAccountId("301991144702-3v9ikfp4lsmokee1utkucj35847eddvg@developer.gserviceaccount.com").setServiceAccountPrivateKey(key).setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/userinfo.email")).build();
} catch (GeneralSecurityException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
我是否尝试其他方法来验证我的Android应用程序?或者我在API代码中遗漏了什么? 提前谢谢你,
答案 0 :(得分:0)
在没有Google用户帐户的情况下验证Android端点是不可能的!我尝试了各种方法,但仍然无效!
所以这是解决这个问题的方法,没有任何用户交互(也许不是正确的但是有效,而且你有强大的身份验证(SHA1 + Google帐户)):
这是我的安卓代码
获取并构建有效凭据
//Get all accounts from my Android Phone
String validGoogleAccount = null;
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
//Just store mail if countain gmail.com
if (account.name.toString().contains("gmail.com")&&account.type.toString().contains("com.google")){
validGoogleAccount=account.name.toString();
}
}
}
//Build Credential with valid google account
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this,"server:client_id:301991144702-5qkqclsogd0b4fnkhrja7hppshrvp4kh.apps.googleusercontent.com");
credential.setSelectedAccountName(validGoogleAccount);
使用此凭据进行安全通话
Campagneendpoint.Builder endpointBuilder = new Campagneendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential);
这是我的API后备代码: API注释
@Api(
scopes=CONSTANTES.EMAIL_SCOPE,
clientIds = {CONSTANTES.ANDROID_CLIENT_ID,
CONSTANTES.WEB_CLIENT_ID,
com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
audiences = {CONSTANTES.ANDROID_AUDIENCE},
name = "campagneendpoint",
version = "v1"
)
方法代码:
public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws UnauthorizedException {
if (user == null) throw new UnauthorizedException("User is Not Valid");
return CampagneCRUD.getInstance().findCampagne(NumPortable);
}
目前,它仅适用于Android(我不知道我们将如何处理IOS ..)..
希望它会对你有帮助!