11.Authorization in Django-Django授权

There are several ways you may want to limit access to data when working with Graphene and Django: limiting which fields are accessible via GraphQL and limiting which objects a user can access.

在使用Graphene和Django时,您可能希望通过几种方法来限制对数据的访问:

限制哪些字段可以通过GraphQL访问,以及限制用户可以访问哪些对象。

Let’s use a simple example model.

让我们使用一个简单的示例模型。

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    published = models.BooleanField(default=False)
    owner = models.ForeignKey('auth.User')

Limiting Field Access 限制现场访问

To limit fields in a GraphQL query simply use the fields meta attribute.

要限制GraphQL查询中的字段,只需使用fields元属性。

from graphene import relay
from graphene_django.types import DjangoObjectType
from .models import Post

class PostNode(DjangoObjectType):
    class Meta:
        model = Post
        fields = ('title', 'content')
        interfaces = (relay.Node, )

conversely you can use exclude meta attribute.

反过来你可以使用exclude元属性。

from graphene import relay
from graphene_django.types import DjangoObjectType
from .models import Post

class PostNode(DjangoObjectType):
    class Meta:
        model = Post
        exclude = ('published', 'owner')
        interfaces = (relay.Node, )

Queryset Filtering On Lists 列表上的查询集筛选

In order to filter which objects are available in a queryset-based list, define a resolve method for that field and return the desired queryset.

为了筛选queryset-based列表中可用的对象,请为该字段定义一个resolve方法并返回所需的queryset。

from graphene import ObjectType
from graphene_django.filter import DjangoFilterConnectionField
from .models import Post

class Query(ObjectType):
    all_posts = DjangoFilterConnectionField(PostNode)

    def resolve_all_posts(self, info):
         return Post.objects.filter(published=True)

User-based Queryset Filtering 基于用户的查询集筛选

If you are using GraphQLView you can access Django’s request with the context argument.

如果使用的是GraphQLView,则可以使用context参数访问Django的请求。

from graphene import ObjectType
from graphene_django.filter import DjangoFilterConnectionField
from .models import Post

class Query(ObjectType):
    my_posts = DjangoFilterConnectionField(PostNode)

    def resolve_my_posts(self, info):
        # context will reference to the Django request
        if not info.context.user.is_authenticated:
            return Post.objects.none()
        else:
            return Post.objects.filter(owner=info.context.user)

If you’re using your own view, passing the request context into the schema is simple.

如果您使用自己的视图,那么将请求上下文传递到模式中很简单。

result = schema.execute(query, context_value=request)

Global Filtering 全局筛选

If you are using DjangoObjectType you can define a custom get_queryset.

如果使用的是djangObjectType,则可以定义一个自定义的get_queryset。

from graphene import relay
from graphene_django.types import DjangoObjectType
from .models import Post

class PostNode(DjangoObjectType):
    class Meta:
        model = Post

    @classmethod
    def get_queryset(cls, queryset, info):
        if info.context.user.is_anonymous:
            return queryset.filter(published=True)
        return queryset

Filtering ID-based Node Access 过滤基于ID的节点访问

In order to add authorization to id-based node access, we need to add a method to your DjangoObjectType.

为了向基于id的节点访问添加授权,我们需要向djangObjectType添加一个方法。

from graphene_django.types import DjangoObjectType
from .models import Post

class PostNode(DjangoObjectType):
    class Meta:
        model = Post
        fields = ('title', 'content')
        interfaces = (relay.Node, )

    @classmethod
    def get_node(cls, info, id):
        try:
            post = cls._meta.model.objects.get(id=id)
        except cls._meta.model.DoesNotExist:
            return None

        if post.published or info.context.user == post.owner:
            return post
        return None

Adding Login Required 添加登录依赖

To restrict users from accessing the GraphQL API page the standard Django LoginRequiredMixin can be used to create your own standard Django Class Based View, which includes the LoginRequiredMixin and subclasses the GraphQLView.:

为了限制用户访问GraphQL API页面,可以使用标准Django[LoginRequiredMixin]创建自己的基于类的标准Django视图,其中包括LoginRequiredMixinGraphQLView的子类:

# views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from graphene_django.views import GraphQLView


class PrivateGraphQLView(LoginRequiredMixin, GraphQLView):
    pass

After this, you can use the new PrivateGraphQLView in the project’s URL Configuration file url.py:

之后,您可以在项目的URL配置文件url.py中使用新的PrivateGraphQLView私有GraphQL视图:

For Django 1.11:

对于Django 1.11:

urlpatterns = [
  # some other urls
  url(r'^graphql$', PrivateGraphQLView.as_view(graphiql=True, schema=schema)),
]

For Django 2.0 and above:

对于Django 2.0及更高版本:

urlpatterns = [
  # some other urls
  path('graphql', PrivateGraphQLView.as_view(graphiql=True, schema=schema)),
]
posted @ 2020-09-25 07:14  双葫  阅读(230)  评论(0编辑  收藏  举报