简体   繁体   English

设置石墨烯中继节点和连接字段的权限

[英]Set permissions on Graphene Relay Node and Connection fields

How can I require authentication/authorization on the tier Node field and allTiers Connection field query below?我如何要求对下面的tier节点字段和allTiers tier连接字段查询进行身份验证/授权?

# schema.py
class TierNode(DjangoObjectType):
    class Meta:
        model = Tier
        filter_fields = []
        interfaces = (graphene.relay.Node,)


class Query(graphene.ObjectType):
    tier = relay.Node.Field(TierNode)
    all_tiers = DjangoFilterConnectionField(TierNode)

You can define a resolver for those fields with auth decorator like so:您可以使用 auth 装饰器为这些字段定义解析器,如下所示:

from graphql_jwt.decorators import login_required

class Query(graphene.ObjectType):
    tier = relay.Node.Field(TierNode)
    all_tiers = DjangoFilterConnectionField(TierNode)


    @login_required
    def resolve_tier(root, info, **kwargs):
        # code for resolving here

This is just using the login_decorator that comes with graphql_jwt but it will work for your custom decorators too if you defined them.这只是使用了login_decorator附带的graphql_jwt但如果您定义了它们,它也适用于您的自定义装饰器。

Furthermore, this also works for when you're resolving a field for TierNode :此外,这也适用于解析TierNode的字段TierNode

class TierNode(DjangoObjectType):
    class Meta:
        model = Tier
        filter_fields = []
        interfaces = (graphene.relay.Node,)

    some_property = graphene.Field("types.SomePropertyType")

    @login_required
    def resolve_some_property(root, info, **kwargs):
        # code for resolving here

You can define authorization or/and authentication decorator like this:您可以像这样定义授权或/和身份验证装饰器:

from functools import wraps

def authorize_required(role):
    def decorator(func):
        @wraps(func)
        def wrapper(instance, info, *args, **kwargs):
            current_user = info.context.user
            if not current_user.is_authenticated:
                raise Exception("Authentication credentials were not provided")
            if not authorize(instance, current_user, role):
                raise Exception(
                    f"{current_user} has no access to {instance} with required {role=}"
                )
            return func(instance, info, *args, **kwargs)
        return wrapper
    return decorator

def authorize(instance, user, role) -> bool:
   # check if user can have access to instance
   # if there is requirement to have certain role

And use it in schema definition:并在模式定义中使用它:

class TierNode(DjangoObjectType):
    class Meta:
        model = Tier
        filter_fields = []
        interfaces = (graphene.relay.Node,)


class Query(graphene.ObjectType):
    tier = relay.Node.Field(TierNode)
    all_tiers = DjangoFilterConnectionField(TierNode)
  
    @authorize_required('user')
    def resolve_tier(self, info, **args):
        # some resolve code

    @authorize_required('admin')
    def resolve_all_tiers(self, info, **args):
        # some resolve code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM