在App Engine中,如何根据电子邮件地址确定用户ID?

13
最新的App Engine SDK(1.2.1)有一个API调用,可以根据用户的电子邮件地址计算用户帐户的ID。(即使用户以后更改其地址,ID仍然保持不变。)有关信息,请参见关于唯一、不透明用户ID的问题。但是,我对这个API调用有一个问题。 user_id()适用于已登录的用户(即来自users.get_current_user),但对于由users.User()构造函数创建的对象,它返回None。**怎么回事?
例如,使用优秀的App Engine Console,这段代码无法正常工作
>>> import google.appengine.api.users
>>> me = google.appengine.api.users.get_current_user()
>>> me
users.User(email='jason.h.smith@gmail.com',_user_id='105261964646342707921')
>>> me.user_id()
'105261964646342707921'
>>> somebody = google.appengine.api.users.User('someone@gmail.com')
>>> somebody
users.User(email='someone@gmail.com')
>>>somebody.user_id()
>>> type(somebody.user_id())
<type 'NoneType'>

我希望有一种简单的方法将电子邮件地址转换为用户ID。如何在提前从Google获取此ID;如果不可能,为什么不行?
编辑:这是目前的解决方法。
感谢Nick Johnson的回答。这是他的解决方案的实现:
>>> from google.appengine.ext import db
>>> from google.appengine.api import users
>>> class User(db.Model):
...   user = db.UserProperty(required=True)
...
>>> def email_to_userid(address):
...   """Return a stable user_id string based on an email address, or None if
...   the address is not a valid/existing google account."""
...   u = users.User(address)
...   key = User(user=u).put()
...   obj = User.get(key)
...   return obj.user.user_id()
>>> email_to_userid('jason.h.smith@gmail.com')
u'105261964646342707921'
>>> email_to_userid('this@is-an-invalid-email-address')
>>> email_to_userid('this@is-an-invalid-email-address') is None
True

你可能需要加上一个警告,即如果给定的电子邮件地址没有Google账户,则不会返回任何用户ID。 - Nick Johnson
在流程结束时,你不应该删除该实体吗? - Uri
这对我不起作用。也许它与ndb不兼容? - Uri
我确认这个在db上可以工作,但在ndb上不行。 - Bernd Verst
可能不适用于 ndb,因为 ndb 对象被缓存在 memcache 中,所以您使用 .get 获取的对象并不来自数据存储。 - mgilson
这里有人知道如何使用NDB获取user_id吗?我已经卡在这里一段时间了。 - Mmm Donuts
2个回答

21

目前的解决方法是创建一个User对象,将其存储到数据存储区,并再次获取。如果电子邮件对应于有效的Google帐户,则返回实体中的User对象将填充其user_id字段。


1
谢谢。我现在正在测试,如果它有效,我会点赞并接受你的答案。 - JasonSmith
+1,它有效。我将在编辑后的问题中放置一些示例代码,希望这个问题可以成为将电子邮件地址转换为用户ID的规范答案。 - JasonSmith
我想在安卓上做同样的事情,有谁可以帮助我吗?谢谢。 - user644458
嗨,尼克,我有点困惑,如果我很蠢请原谅。您是否意味着通过上述解决方法,提供了一种以编程方式测试所提供的电子邮件地址是否与有效的Gmail帐户相关联的方法 - 因为这是我的合法用例。但是,首先我无法使用Java使其工作。其次,它似乎与此答案相矛盾,该答案暗示故意不支持此类测试:http://stackoverflow.com/questions/13313877/how-to-validate-a-gmail-address-in-java/13314114#13314114 - doright
好的,现在运行正常了,所以我猜应该是可以的。谢谢! - doright
有人有在Java中完成此操作的代码片段吗? - Chad

1
为了让建议的解决方案与NDB协同工作,只需在get方法中添加use_cache=False、use_memcache=False。即: obj = key.get(use_cache=False, use_memcache=False) 这样可以确保从Datastore获取实体时,user_id参数已填充(仅当这是有效的Google帐户时)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接