6

我正在尝试使用 Pyramid 文档的“使“用户对象”可用作请求属性“示例来制作用户数据的可访问缓存。

他们使用此代码将用户对象返回给 set_request_property:

from pyramid.security import unauthenticated_userid

def get_user(request):
    # the below line is just an example, use your own method of
    # accessing a database connection here (this could even be another
    # request property such as request.db, implemented using this same
    # pattern).
    dbconn = request.registry.settings['dbconn']
    userid = unauthenticated_userid(request)
    if userid is not None:
        # this should return None if the user doesn't exist
        # in the database
        return dbconn['users'].query({'id':userid})

我不明白他们为什么使用 unauthenticated_userid(request) 从数据库中查找用户信息……这不是不安全吗?这意味着用户可能没有登录,那么为什么要使用该 ID 从数据库中获取私人信息?

不应该

    userid = authenticated_userid(request)

而是用来确保用户已登录?使用 unauthenticated_userid(request) 有什么好处?请帮助我了解这里发生了什么。

4

3 回答 3

3

unauthenticated_userid通话是更便宜的通话;它从请求中查找用户 ID,而无需再次执行整个身份验证过程。

这里的关键概念是这个词。您应该只在已授权的视图中使用该方法。换句话说,当您到达使用unauthenticated_userid您的代码时,您已经验证了用户,并且特别不想为这个特定的调用再次这样做。

针对后端持久存储对用户进行身份验证可能会很昂贵,尤其是在此类存储不支持缓存的情况下。API 方法是一种优化,unauthenticated_userid其中请求基本上是您的userid缓存。

于 2012-09-22T21:09:07.780 回答
2

这是一个迟到的回复,但它被链接为 Pyramid 的一些用户的混淆来源。

这里接受的答案不是unauthenticated_userid用于request.user. 它与性能无关。

使用它的原因unauthenticated_userid是因为它可以更轻松地在应用程序之间重用身份验证策略,只需进行较小的修改。您的应用程序需要一个“事实来源”来确定是否允许将用户视为已通过身份验证,并且通常策略的内部逻辑不足以做出此决定。一个有效的 cookie 很好,但您通常希望在信任它之前与您的后端进行验证。太好了,那么我们把这个逻辑放在哪里呢?那么unauthenticated_userid没有意义,因为它是策略的可重用部分,专门专注于解析请求标头。你可以把它放进去,authenticated_userid但这种方法不是你在应用程序中通常关心的方法。您通常request.user在您的应用程序中使用(您可能很少关心request.authenticated_userid直接),最后request.user是功能的超集——它提供了一个完整的用户对象,而不仅仅是一个 id。在大多数情况下,在不验证整个对象的情况下验证 id 是很愚蠢的。我们只能有一个“真相来源”,因此配方声明它是request.user。groupfinder(因此authenticated_userid)现在可以依赖request.user并相信它从那里返回的内容已通过后端正确验证。也已经被具体化,因此自然会request.user加快后续调用。request.authenticated_userid

于 2017-04-24T14:34:10.460 回答
1

看起来 Martijn Pieters 是对的。

我的微基准测试(在我的项目中,我使用 Redis 作为用户和其他一切的数据库):

print ('start test')
t1 = time()
authenticated_userid(self.request)
print ('authenticated: ' + str(time()-t1))
t1 = time()
unauthenticated_userid(self.request)
print ('unauthenticated: ' + str(time()-t1))
print ('test_stop')

结果:

start test
REDIS AUTH! # <-- actually this is query to groups finder in Redis
authenticated: 0.00032901763916
unauthenticated: 7.31945037842e-05
test_stop

它经过了几次测试,结果是不变的 :) 你认为我应该在 Pyramid 文档中添加 Martijn 对那篇文章的回答以使事情更“清晰”吗?:)

于 2012-09-22T21:36:37.013 回答