为什么full = true在Django Tastypie中断资源行为? [英] Why does full=true breaks resources behaviour in Django Tastypie?

查看:140
本文介绍了为什么full = true在Django Tastypie中断资源行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在相关领域使用 full = true 是非常方便的功能,以防止客户端提出太多请求获取必要的信息。

Using full=trueon related fields is very convenient feature to prevent client from doing too many requests to get necessary information.

然而,我真的不明白为什么在使用相关字段后,Meta类的指令不会被遵循。

Nevertheless, I really don't understand why the "instructions" in Meta Class are not followed as soon as you use a related field.

这里是一个简单的例子:

Here is a simple example:

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请求返回a在/ client_users / 1(client_user 1与用户1相关)中的GET请求返回client_user 1的数据 AND

  • 用户1的数据(我没有期望得到用户1的信息,因为它是未经授权的。)

请注意,我得到与allowed_methods,验证等相同的行为。
这种行为对我来说是一个负担,因为它迫使我在全部删除full = true以避免安全漏洞。

Note that I got the same behaviour with allowed_methods, validation, etc. This behaviour is a burden to me since it forces me to remove full=true everywhere to avoid security holes.

我做错了什么?

推荐答案

你期望Tastypie在这种情况下做什么?我想你想看到一个401未经授权给您的ClientUserResource GET,但在我看来,这将是相当不一致的。您指定ClientUserResource没有定义明确的授权(因此可以免费获取访问权限),但遵循逻辑,您希望根据其他资源的授权来查看响应。

What do you expect Tastypie to do in that case? I suppose you would like to see a 401 Unauthorized to your ClientUserResource GET, but in my opinion this would be rather inconsistent. You are specifying that ClientUserResource has no explicit Authorization defined (and thus free GET access) but following your logic you would like to see the response according to another resource's authorization.

如果你想避免安全漏洞,最好不要使用full = True。您可以覆盖水合物方法以根据所需的规则返回扩展对象,或者对于考虑到UserResource规则的ClientUserResource使用类似的Authentication类(在这种情况下,full = True将正确控制)全部资源访问)。

If you want to avoid security holes, it would be best indeed to not use full=True. You could overwrite the hydrate method to return the expanded object or not according to the rules you want, or use a similar Authentication class for ClientUserResource that takes into consideration the rules of UserResource (in this case full=True would be ok as you are controlling the full resource access).

编辑:我的两个提出的解决方案更详细。

My two proposed solutions with more detail.

1 。相同的授权

有了这个我的意思是,如果你想保护你的相关资源,而使用 full = True ,你应该在两个资源中使用相同的授权(或者在ClientUserResource中使用更严格的授权,以使您的UserResource从不泄露)。事实上,我不能想到一个你想要有两个完全不同的授权逻辑的情况,然后在另一个中包含一个资源。

With this I mean that, if you want to protect your related resource while using full=True, you should use the same authorization in both resources (or a more strict authorization in ClientUserResource so your UserResource never gets leaked). In fact, I can't think of a case in which you would like to have two complete distinct authorization logics and then include one resource inside of another.

在你的例子中,你应该添加authorization = NothingAuthorization()。如果你真的想要第二类的不同身份验证行为,我们来看看另一个选项。

In your example, you should add authorization = NothingAuthorization(). If you really want a different authentication behavior for the second class let's see another option.

2。覆盖脱水方法或obj_create

在这种情况下,您应该删除 full = True ,并自行提供该行为实例覆盖脱水方法。在这种方法中,您可以访问您的请求和数据,以便执行一些逻辑。

In this case, you should delete the full=True and provide that behavior yourself, by for instance overwriting the dehydrate method. In this method you have access to your request and data so you can perform some logic.

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

这可能看起来像丑,因为你不使用您的资源中提供授权逻辑的任何授权类。我想你可以在UserResource中建立一个UserResource,并附带请求并对其进行测试,但是我认为这是因为我们期待的奇怪的行为变得越来越复杂(两种资源的不同认证模型是非常耦合的) 。

This can look kind of "ugly", as you are not using any Authorization class in your resource that provides the authorization logic. I suppose you could build in the dehydrate method a UserResource along with the request and test there the authorization, but I think it gets more and more complicated for the strange behavior we are expecting here (different authentication models for two resources which are very coupled).

这篇关于为什么full = true在Django Tastypie中断资源行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆