I have been doing extensive research on how to authenticate your client (Android, iOS, web-app) with Cloud Endpoints without requiring your user to use their Google
So you don't have any user specific info, but just want to ensure that only your app is able to communicate with your backend... This is what i think,
change
@Api(name = "myApi", version = "v1",
namespace = @ApiNamespace(ownerDomain = "${endpointOwnerDomain}",
ownerName = "${endpointOwnerDomain}",
packagePath="${endpointPackagePath}"),
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID,
Constants.IOS_CLIENT_ID,
Constants.API_EXPLORER_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE})
{
...
}
to
@Api(name = "myApi", version = "v1",
namespace = @ApiNamespace(ownerDomain = "${endpointOwnerDomain}",
ownerName = "${endpointOwnerDomain}",
packagePath="${endpointPackagePath}"),
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.ANDROID_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE})
{
...
}
The Client ID is generated from the signature of your app. It can't be replicated. If you only allow your endpoints to accept requests from the Android App, your problem would be solved.
Tell me if this works.
I have implemented Endpoint Auth using a custom header "Authorization" and it works just fine. In my case this token is set after login but should work all the same with your app. Check your tests because the value should be there. The way to retrieve that header is indeed:
String Auth = req.getHeader("Authorization");
You could take it a step further and define your own implementations of an Authenticator and apply it to your secure API calls.
Faced the same problem to find a solution to call my API safely from my endpoints, without using Google Account. We can't decompile an IOS App (Bundle), but decompile an Android App is so simple..
The solution I found is not perfect but do the job pretty good:
Example:
@ApiMethod(name = "sayHi")
public void sayHi(@Named("name") String name, @Named("Token") String token) {
if (token == tokenStoreOnAPIServer) {
//Allow it
} else {
//Refuse it and print error
}
}
Not THE perfect secure solution, but it works, and it will be really really (really) difficult to find the real API key for anyone who try to read your code after decompilation.