检索Google用户对象的ID值

时间:2016-11-22 17:31:53

标签: python google-cloud-platform google-cloud-endpoints

我一直很困惑。我一直在使用Google的用户对象,可以在此处找到:

https://cloud.google.com/appengine/docs/python/refdocs/google.appengine.api.users#google.appengine.api.users.User

在阅读了一些资源之后,我被告知存储用户对象本身并不是一个好主意,因为电子邮件可能会发生变化。谷歌推荐的是,你应该存储User_Id本身,因为它一直是安全的(即,它始终是静态的)。

当我获得当前用户并尝试使用用户对象上的user_id()方法获取User_Id值时,我得到None值响应。

current_user = endpoints.get_current_user()
print current_user.user_id()
>> None

但是,如果我将current_user保存为NDB中的UserProperty然后检索相同的值,我会得到user_id。例如:

google_user = ndb.UserProperty(required = True)

print google_user.user_id()
>> 12345678901234567890

如何处理Google用户对象?更重要的是,为什么在NDB保存值之前user_id值为None?这是一种帐户/电子邮件验证吗?

您可以在此处找到Google的建议:

https://cloud.google.com/appengine/docs/python/users/userobjects

"我们强烈建议您不要存储UserProperty,因为它包含电子邮件地址以及用户的唯一ID。如果用户更改了他们的电子邮件地址,并将他们旧的,存储的用户与新用户值进行比较,则他们不会匹配。相反,请考虑使用用户用户ID值作为用户的稳定唯一标识符。"

编辑:我应该提一下,我正在localhost进行测试。部署applcation时endpoints.get_current_user()处理方式有何不同?

这是Google使用的示例:

class ModelWithUser(ndb.Model):
    user_id = ndb.StringProperty()
    color = ndb.StringProperty()

    @classmethod
    def get_by_user(cls, user):
        return cls.query().filter(cls.user_id == user.user_id()).get()

如果我通过当前经过身份验证的用户(我无权访问)通过user_id查询ModelWithUser,我打算如何从{{1}获取用户}?尔加。

2 个答案:

答案 0 :(得分:1)

好的,所以在通过谷歌搜索挖掘之后,我遇到了关于如何获得当前用户ID而没有访问数据存储的问题:

https://code.google.com/p/googleappengine/issues/detail?id=8848

谷歌的官方回应是,这是已知问题,不会修复:

“修复此问题不在我们的路线图中 - Google ID令牌包含G +用户ID,而不是App Engine用户ID,因此提供的App Engine用户对象不能包含App Engine用户ID。我们建议您使用其中一个上面提到的解决方法。“

此解决方法(来自Google开发人员):https://code.google.com/p/googleappengine/issues/detail?id=8848#c39

def _getUserId():
    """A workaround implementation for getting userid."""
    auth = os.getenv('HTTP_AUTHORIZATION')
    bearer, token = auth.split()
    token_type = 'id_token'
    if 'OAUTH_USER_ID' in os.environ:
        token_type = 'access_token'
    url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?%s=%s'
           % (token_type, token))
    user = {}
    wait = 1
    for i in range(3):
        resp = urlfetch.fetch(url)
        if resp.status_code == 200:
            user = json.loads(resp.content)
            break
        elif resp.status_code == 400 and 'invalid_token' in resp.content:
            url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?%s=%s'
                   % ('access_token', token))
        else:
            time.sleep(wait)
            wait = wait + i
    return user.get('user_id', '')

尽管我喜欢在Google的堆栈中工作,但我承认 - 这很奇怪。

编辑:

另一种解决方法可以在这里找到:

How can I determine a user_id based on an email address in App Engine?

答案 1 :(得分:0)

question是相关的(类UserProperty仅用于向后兼容现有数据存储模式)。

而且,正如您在问题中引用的文档中所述:

  

USER_ID()

     

获取用户的用户ID。

     

返回

     

永久唯一标识字符串或无。如果是电子邮件   地址已明确设置,这将返回无。

是否明确设置了用户的电子邮件地址?