在Google App Engine中生成唯一且不透明的用户ID
我正在开发一个应用程序,允许注册用户创建或上传内容,同时让匿名用户可以查看这些内容,并浏览注册用户的页面来找到这些内容。这和像Flickr这样的网站很相似,用户可以在上面浏览其他用户的页面。
为了实现这个功能,我需要一种方法来识别匿名HTTP GET请求中的用户。用户应该能够输入 http://myapplication.com/browse/<userid>/<contentid>
这样的链接,直接访问到正确的页面。这个链接应该是唯一的,但出于隐私考虑,我不想使用用户的电子邮件地址。
通过Google App Engine,我可以获取与用户关联的电子邮件地址,但正如我所说,我不想使用这个。我可以让我的应用用户在注册时选择一个独特的用户名,但如果可能的话,我希望这个步骤是可选的,以便让注册过程尽可能简短。
另一个选择是在注册过程中生成一个随机的cookie(比如GUID),然后使用这个cookie。不过,我没有看到一个明显的方法来保证这个cookie的唯一性,而不需要访问数据库。
有没有办法在给定的App Engine用户对象中,获取一个可以这样使用的唯一标识符?
我在寻找一个Python的解决方案——我忘了GAE现在也支持Java。不过,我认为无论使用哪种语言,技术应该是类似的。
3 个回答
你是说会话 cookie吗?
可以试试这个链接。
正如DzinX所说,想要创建一个可以验证但不需要查询数据库的密钥,唯一的方法就是使用加密或者加密哈希。
给用户一个随机数字,然后用一个私钥对它进行哈希处理或加密。虽然这样做还是有一点小风险,可能会出现重复的情况,但你可以在创建密钥时查询数据库,如果发生重复,就换一个随机数字。确保这个随机数字是安全的,并且加上一个长的服务器端随机数字,以防止被攻击者利用。
最终你会得到一个像Google文档密钥那样的令牌,基本上是一个证明用户已通过验证的签名,可以在不查询数据库的情况下进行验证。
不过,考虑到GAE的定价和bigtable的速度,如果你真的不能使用Google自己的认证,使用会话ID可能会更好。
我觉得你应该区分两种用户:
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
不是一个随机函数,它对于给定的数据总是返回相同的结果,但它被证明在实际应用中是不可逆的,所以你可以安全地在网站上展示这个哈希值,而不会泄露用户的邮箱地址。此外,你可以放心地认为,不同邮箱的哈希值不会相同(虽然有可能相同,但这种情况发生的概率非常非常小)。想了解更多关于哈希函数的信息,可以查看 维基百科的相关条目。
你的时机真是太好了:就在昨天,SDK发布了一个新版本,支持独特且永久的用户ID。这些ID完全符合你提到的所有要求。