有没有办法保护Google云端点proto数据存储? [英] Is there a way to secure Google cloud endpoints proto datastore?

查看:151
本文介绍了有没有办法保护Google云端点proto数据存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的设置:




  1. 使用endpoints_proto_datastore的Python应用引擎

  2. iOS,endpoints Obj -C客户端库生成器



背景



Google云端点API,并且运行得非常快。它运行良好,使用iOS模拟器中的测试应用程序,并使用Google的API Explorer。 API目前向所有用户开放,无需身份验证。



我想要:设置API密钥或系统凭证,以供应用程序来确保它可以访问api - 所有其他人都将被拒绝。



Google终端验证文档中的方法 (1)将使用 Google Developers Console (2)创建OAuth 2.0客户端ID。所以我创建了一个类型为iOS的安装应用程序的ID。到目前为止很好。



在应用程序中,GTLService对象看起来像这样...

   - (GTLServiceDemogaeapi *)myApiService {
GTMOAuth2Authentication * auth = [[GTMOAuth2Authentication alloc] init];
auth.clientID = @10 ??????????????????? ie.apps.googleusercontent.com;
auth.clientSecret = @z ???????????? 3;
auth.scope = @https://www.googleapis.com/auth/userinfo.email;

static GTLServiceDemogaeapi * service = nil;
if(!service){
service = [[GTLServiceDemogaeapi alloc] init];
service.authorizer = auth;
service.retryEnabled = YES;
[GTMHTTPFetcher setLoggingEnabled:YES];
}
退货服务;
}

在GAE上,我指定了(allowed_client_ids)方法...
$ b $ $ p $ @ endpoints.api(name ='demogaeapi',version ='v1',
allowed_client_ids = ['10 ????????????? ie.apps.googleusercontent.com',
endpoints.API_EXPLORER_CLIENT_ID],
scopes = [endpoints.EMAIL_SCOPE],
description ='My Demo API')
class MyApi(remote.Service):

@ TestModel.method(path ='testmodel / {id}',name ='testmodel.insert ',http_method ='POST')
def testModelInsert(self,test_model):

current_user = endpoints.get_current_user()
如果current_user是None:
提升端点.UnauthorizedException('Invalid token。')



问题



current_user 总是 None ,所以该方法总会引发异常。 ars,这是一个已知问题问题8848:Google Cloud Enpoints get_current_user API不会填充user_id (3),并且很快就无法修复。



选项?




  1. 等待Google修复问题8848.真的不行,我们有产品发布!

编辑:2015年5月15日 - Google发行了8848状态WontFix。


  1. 我看到可以使用API​​密钥,但是我可以创建一个 - 我还没有找到启用它的方法在后端。我也注意到这种方法有一个很大的漏洞,Google的API资源管理器可以击败它见SO问题(4)。

  2. @ endpoints.api参数:auth_level 这里介绍(5),提供答案?我试过使用:

      @ endpoints.api(name ='demogaeapi',version ='v1',
    auth_level = endpoints.AUTH_LEVEL.REQUIRED,
    scopes = [endpoints.EMAIL_SCOPE],
    description ='My Demo API')

    但是能够在不使用凭证的情况下使用客户端应用程序中的api。所以它显然没有添加任何验证。

  3. 在持有共享密钥的客户端查询中添加一个hiddenProperty。正如bossylobster here (6)和Carlos here (7)所述。我尝试过,但无法看到如何获取原始请求对象(另一个问题的主题如何获取)使用endpoints_proto_datastore.ndb?时的请求对象)。

      @ TestModel.method(path ='testmodel / { ('self',test_model):

    mykey,keytype = request.get_unrecognized_field_info('hiddenProperty')
    if mykey!='my_supersecret_key':
    raise endpoints.UnauthorizedException('No,you dont!')


编辑:另一个选项已浮出水面:


  1. 使用 Google开发者控制台(2)创建服务帐户。无需用户许可(通过用户界面),即可使用此帐户访问API。但是,Google似乎将可以通过这种方式添加到15或20的应用程序数量限制在此。请参阅Google OAuth2 doc(8)。



问题



有人知道吗?我如何才能让这些选项起作用?或者我应该以不同的方式来解决这个问题?



正如你所看到的,我需要指导,帮助和想法... ...

$ hr

由于我需要10个信誉才能发布2个以上的链接:以下是我必须提取并添加为参考的链接。


  1. cloud.google.com/appengine/docs/python/endpoints/ auth

  2. console.developers.google.com /

  3. code.google.com/p/googleappengine/issues/detail?id=8848
  4. li>
  5. stackoverflow.com/a/26133926/4102061

  6. cloud.google.com/appengine/docs/python/endpoints/create_api

  7. stackoverflow.com/a/16803274/4102061

  8. stackoverflow.com/a/26133926/4102061

  9. developers.google.com / accounts / docs / OAuth2


解决方案

一个很好的问题和一个真正的问题。我通过拥有自己的用户数据库表来解决这个问题。 Long 键(我使用Java)是在写入时自动生成的,这是我用来唯一标识用户的值。此外,该表还会写入Google ID(如果通过网页呼叫时提供),电子邮件地址和iOS ID(在未登录Google帐户的情况下使用iOS应用程序时)。



当我的AppEngine端点被调用时,我使用 User 参数中的 提供的信息(只是经过身份验证的电子邮件地址为已登录的客户端)或单独的,可选的 iosid 参数,以便从表格中提取我的内部用户标识号码,并使用该号码来唯一标识我的用户。

我使用同一个表来存储其他用户特定的信息,所以它实际上与尝试使用 current_user 作为主键,除了我必须为查找索引三个字段(googleid,email,iosid)外。


my setup:

  1. Python, google app engine using endpoints_proto_datastore
  2. iOS, endpoints Obj-C client library generator

Background

I've setup a test Google cloud endpoints api and had it running pretty quickly. It works great, using the test app in the iOS simulator, and using Google's APIs Explorer. The API is currently open to all with no authentication.

I'd like to: setup an API-key or system-credential that can be used by the app to ensure it alone can access the api - with all others being refused.

The method in the Google Endpoints Auth docs (1) is to create an OAuth 2.0 client ID using the Google Developers Console (2). So I have created an ID for an Installed Application of type: iOS. So far so good.

In the app the GTLService Object looks like this...

-(GTLServiceDemogaeapi *)myApiService {
    GTMOAuth2Authentication *auth = [[GTMOAuth2Authentication alloc] init];
    auth.clientID = @"10???????????????????ie.apps.googleusercontent.com";
    auth.clientSecret = @"z????????????3";
    auth.scope = @"https://www.googleapis.com/auth/userinfo.email";

    static GTLServiceDemogaeapi *service = nil;
    if (!service) {
        service = [[GTLServiceDemogaeapi alloc] init];
        service.authorizer = auth;
        service.retryEnabled = YES;
        [GTMHTTPFetcher setLoggingEnabled:YES];
    }
    return service;
 }

On GAE I've specified the (allowed_client_ids and added a user check to the methods...

@endpoints.api(name='demogaeapi', version='v1',
               allowed_client_ids=['10?????????????ie.apps.googleusercontent.com',
               endpoints.API_EXPLORER_CLIENT_ID],
               scopes=[endpoints.EMAIL_SCOPE],
               description='My Demo API')
class MyApi(remote.Service):

    @TestModel.method(path='testmodel/{id}', name='testmodel.insert', http_method='POST')
    def testModelInsert(self, test_model):

        current_user = endpoints.get_current_user()
        if current_user is None:
            raise endpoints.UnauthorizedException('Invalid token.')

The issue

current_user is always None so the method will always raise an exception. It appears that this is a known problem Issue 8848: Google Cloud Enpoints get_current_user API doesn't fill user_id (3) with no prospect of a fix soon.

Options?

  1. Wait until google fix Issue 8848. Can't really, we have a product to release!

EDIT: 15 May 2015 - Google made Issue 8848 status WontFix.

  1. I saw that it may be possible to use an API Key but while I have been able to create one - I have not found a way to enable it on the backend. I also note this method has a big hole where Google's APIs Explorer can defeat it see SO question (4).

  2. Does the @endpoints.api Argument: auth_level, described here (5), provide an answer? I tried using:

    @endpoints.api(name='demogaeapi', version='v1',
           auth_level=endpoints.AUTH_LEVEL.REQUIRED,
           scopes=[endpoints.EMAIL_SCOPE],
           description='My Demo API')
    

    But was able to use the api from the client app without using credentials. So it clearly did not add any authentication.

  3. Add a hiddenProperty to the client query holding a shared secret key. As described by bossylobster here (6) and Carlos here (7). I tried this but cannot see how to get at the raw request object (subject of another question How to get at the request object when using endpoints_proto_datastore.ndb?).

    @TestModel.method(path='testmodel/{id}', name='testmodel.insert', http_method='POST')
    def testModelInsert(self, test_model):
    
        mykey,keytype = request.get_unrecognized_field_info('hiddenProperty')
        if mykey != 'my_supersecret_key':
            raise endpoints.UnauthorizedException('No, you dont!')
    

EDIT: Another option has surfaced:

  1. Create a Service Account using the Google Developers Console (2). Use this account to gain access to the API without the need for user consent (via UI). However, Google appear to limit the number of apps that can be added this way to 15 or 20. See Google OAuth2 doc (8). We will likely exceed the limit.

The Question

Does anyone know how I can get any of these options working? Or should I be approaching this in a different way?

As you can see I'm in need of guidance, help, ideas...


As I need 10 reputation to post more than 2 links: here are the links I had to extract and add as references. Sort of ruined the flow of the question really.

  1. cloud.google.com/appengine/docs/python/endpoints/auth
  2. console.developers.google.com/
  3. code.google.com/p/googleappengine/issues/detail?id=8848
  4. stackoverflow.com/a/26133926/4102061
  5. cloud.google.com/appengine/docs/python/endpoints/create_api
  6. stackoverflow.com/a/16803274/4102061
  7. stackoverflow.com/a/26133926/4102061
  8. developers.google.com/accounts/docs/OAuth2

解决方案

An excellent question and a real problem. I solved it by having my own "user" database table. The Long key (I use Java) is auto-generated on write and that is the value I use to uniquely identify the user from then on. Also written to that table are the Google ID (provided if being called through a web page), email address, and iOS id (when using the iOS app while not signed-in to a Google account).

When my AppEngine endpoint gets called, I use information that is present in the User parameter (just the authenticated email address for signed-in clients) or a separate, optional iosid parameter in order to fetch my internal userid number from said table and use that from then on to uniquely identify my user.

I use the same table to store other user-specific information, too, so it really isn't any different than trying to use current_user as a primary key other than I had to make three fields (googleid, email, iosid) indexed for lookup.

这篇关于有没有办法保护Google云端点proto数据存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆