为什么full=true会破坏Django tastype中的资源行为?

2024-09-30 20:30:32 发布

您现在位置:Python中文网/ 问答频道 /正文

在相关字段上使用full=true是一种非常方便的特性,可以防止客户机执行太多请求以获取必要的信息。你知道吗

尽管如此,我真的不明白为什么你一使用相关的字段就不遵循元类中的“指令”。你知道吗

下面是一个简单的例子:

class UserResource(ModelResource):
    class meta():
        queryset = User.objects.all()
        resource_name = 'users'
        authorization = NothingAuthorization() # Returns None or [] on GET requests

class ClientUserResource(ModelResource):
    user = fields.ForeignKey(UserResource, 'user', full=True)

    class meta():
        queryset = ClientUser.objects.all()
        resource_name = 'client_users'
        # Some other required fields

那么

  • /users/1上的GET请求返回401响应(正如预期的那样,完美!)你知道吗
  • /client\u users/1上的GET请求(client\u user 1与user 1相关)返回client\u user 1的数据user 1的数据(我没想到会得到user 1的信息,因为它是未经授权的)

注意,我在允许的方法、验证等方面得到了相同的行为。 这种行为对我来说是一种负担,因为它迫使我到处删除full=true以避免安全漏洞。你知道吗

我做错什么了?你知道吗


Tags: client信息truegetobjectsallusersresource
1条回答
网友
1楼 · 发布于 2024-09-30 20:30:32

你希望Tastypie在这种情况下做什么?我想您希望看到一个401未经授权的客户端用户资源得到,但在我看来,这将是相当不一致的。您指定ClientUserResource没有定义明确的授权(因此可以自由访问),但是按照您的逻辑,您希望看到根据另一个资源的授权的响应。你知道吗

如果您想避免安全漏洞,最好不要使用full=True。您可以根据所需的规则覆盖hydrate方法以返回展开的对象或不返回展开的对象,或者对ClientUserResource使用类似的身份验证类,该类考虑UserResource的规则(在本例中,当您控制完全资源访问时,full=True是可以的)。你知道吗

编辑:我的两个更详细的解决方案。你知道吗

<强>1。相同授权

我的意思是,如果您想在使用full=True时保护您的相关资源,您应该在两个资源中使用相同的授权(或者在ClientUserResource中使用更严格的授权,这样您的UserResource就不会泄露)。事实上,我想不出这样一种情况:您希望拥有两个完全不同的授权逻辑,然后将一个资源包含在另一个资源中。你知道吗

在您的示例中,应该添加authorization=NothingAuthorization()。如果您真的希望第二个类有不同的身份验证行为,那么让我们看看另一个选项。你知道吗

<强>2。覆盖脱水方法或对象创建

在这种情况下,您应该删除full=True并自己提供该行为,例如覆盖dehydrate方法。在这个方法中,您可以访问您的请求和数据,这样您就可以执行一些逻辑。你知道吗

class ClientUserResource(ModelResource):

    class meta():
        queryset = ClientUser.objects.all()
        resource_name = 'client_users'

    def dehydrate(self, bundle):
        # Do whatever you want, for instance, authorize only one user, and then add
        # to the result your desired info as full=True would do
        if bundle.request.user.username == "admin":
            bundle.data['user'] = {'username': "admin",
                                   'email': "admin@gmail.com", 
                                   ...}}
        return bundle

这看起来有点“丑陋”,因为您在资源中没有使用任何提供授权逻辑的授权类。我想您可以在dehydrate方法中构建一个UserResource和请求,并在那里测试授权,但是我认为对于我们在这里期望的奇怪行为(两个非常耦合的资源的不同身份验证模型),它变得越来越复杂。你知道吗

相关问题 更多 >