【问题标题】:Set permissions on Graphene Relay Node and Connection fields设置石墨烯中继节点和连接字段的权限
【发布时间】:2021-11-06 14:03:51
【问题描述】:

我如何要求对下面的tier 节点字段和allTiers 连接字段查询进行身份验证/授权?

# 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)

【问题讨论】:

    标签: graphql relay graphene-python graphene-django graphql-python


    【解决方案1】:

    您可以使用 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
    

    这只是使用graphql_jwt 附带的login_decorator,但如果您定义它们,它也适用于您的自定义装饰器。

    此外,这也适用于解析 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
    
    

    【讨论】:

    • 谢谢@jech-chua。定义解析器似乎适用于除 Node 和 Connection 字段之外的所有内容。也许这是一个石墨烯错误?
    • 你遇到过什么问题?这就是我们在当前项目中保护端点/字段的方式。
    【解决方案2】:

    您可以像这样定义授权或/和身份验证装饰器:

    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
    

    并在模式定义中使用它:

    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
    

    【讨论】:

      猜你喜欢
      • 2017-05-13
      • 2018-06-27
      • 2021-05-10
      • 2018-09-19
      • 2020-08-02
      • 2017-05-11
      • 2019-10-04
      • 2019-04-03
      • 2020-08-11
      相关资源
      最近更新 更多