Authenticating your client to Cloud Endpoints without a Google Account login

廉价感情. 提交于 2019-11-28 20:23:44

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:

  1. On android APP, I just create an constant String variable, named APIKey, with simply content (For example "helloworld145698")
  2. Then I encrypt it with sha1, next md5, and finally sha1 (Order and frequency of encryption up to you) and store the variable on SharedPref (For Android) in private mode (Do this action on an random class in your App) It's this result encrypted I authorize on my Backend !
  3. On my backend, I just add a parameter (named token for exemple) on every request

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
    } 

}
  1. On android, active ProGuard for obfuscated your code. It will be really unreadable for anyone who tried to decompile your app (Reverse engineering is really hardcore)

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!