设置石墨烯中继节点和连接字段的权限
Posted
技术标签:
【中文标题】设置石墨烯中继节点和连接字段的权限【英文标题】: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)
【问题讨论】:
【参考方案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
【讨论】:
以上是关于设置石墨烯中继节点和连接字段的权限的主要内容,如果未能解决你的问题,请参考以下文章
使用石墨烯和 SQLalchemy 为 GraphQL 设置权限很热门