在Google App Engine中生成唯一且不透明的用户ID

9 投票
3 回答
6554 浏览
提问于 2025-04-15 11:12

我正在开发一个应用程序,允许注册用户创建或上传内容,同时让匿名用户可以查看这些内容,并浏览注册用户的页面来找到这些内容。这和像Flickr这样的网站很相似,用户可以在上面浏览其他用户的页面。

为了实现这个功能,我需要一种方法来识别匿名HTTP GET请求中的用户。用户应该能够输入 http://myapplication.com/browse/<userid>/<contentid> 这样的链接,直接访问到正确的页面。这个链接应该是唯一的,但出于隐私考虑,我不想使用用户的电子邮件地址。

通过Google App Engine,我可以获取与用户关联的电子邮件地址,但正如我所说,我不想使用这个。我可以让我的应用用户在注册时选择一个独特的用户名,但如果可能的话,我希望这个步骤是可选的,以便让注册过程尽可能简短。

另一个选择是在注册过程中生成一个随机的cookie(比如GUID),然后使用这个cookie。不过,我没有看到一个明显的方法来保证这个cookie的唯一性,而不需要访问数据库。

有没有办法在给定的App Engine用户对象中,获取一个可以这样使用的唯一标识符?

我在寻找一个Python的解决方案——我忘了GAE现在也支持Java。不过,我认为无论使用哪种语言,技术应该是类似的。

3 个回答

1

你是说会话 cookie吗?

可以试试这个链接


正如DzinX所说,想要创建一个可以验证但不需要查询数据库的密钥,唯一的方法就是使用加密或者加密哈希。

给用户一个随机数字,然后用一个私钥对它进行哈希处理或加密。虽然这样做还是有一点小风险,可能会出现重复的情况,但你可以在创建密钥时查询数据库,如果发生重复,就换一个随机数字。确保这个随机数字是安全的,并且加上一个长的服务器端随机数字,以防止被攻击者利用。

最终你会得到一个像Google文档密钥那样的令牌,基本上是一个证明用户已通过验证的签名,可以在不查询数据库的情况下进行验证。

不过,考虑到GAE的定价和bigtable的速度,如果你真的不能使用Google自己的认证,使用会话ID可能会更好。

3

我觉得你应该区分两种用户:

1) 已经通过谷歌账号登录的用户,或者已经用非谷歌邮箱在你的网站上注册过的用户。

2) 第一次访问你的网站,并且没有以任何方式登录的用户。

对于第二种情况,我觉得没有其他办法,只能生成一些随机字符串(比如用 uuid.uuid4() 或者从这个用户的会话cookie键生成),因为匿名用户身上没有任何独特的信息。

而对于已经登录的用户,你已经有一个独特的标识符——他们的邮箱地址。我理解你对隐私的担忧——你不应该把它当作标识符来使用。那我们可以生成一个看起来随机的字符串,但实际上是从邮箱地址生成的。哈希函数非常适合这个目的。举个例子:

>>> import hashlib

>>> email = 'user@host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'

>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7

因为 hashlib.sha1 不是一个随机函数,它对于给定的数据总是返回相同的结果,但它被证明在实际应用中是不可逆的,所以你可以安全地在网站上展示这个哈希值,而不会泄露用户的邮箱地址。此外,你可以放心地认为,不同邮箱的哈希值不会相同(虽然有可能相同,但这种情况发生的概率非常非常小)。想了解更多关于哈希函数的信息,可以查看 维基百科的相关条目

7

你的时机真是太好了:就在昨天,SDK发布了一个新版本,支持独特且永久的用户ID。这些ID完全符合你提到的所有要求。

撰写回答