Permissions 在graphene django中分离公共和私有API的推荐最佳实践是什么?

Permissions 在graphene django中分离公共和私有API的推荐最佳实践是什么?,permissions,graphql,graphene-django,Permissions,Graphql,Graphene Django,我已经看到了一些关于如何在石墨烯中实现许可系统的讨论,但除了这些讨论之外,还没有看到任何明确的实际结果。关于这一主题的一些讨论示例如下: 不幸的是,这些都不推荐在graphene中实现权限的首选方法。有人知道目前最好的做法是什么吗?首先,只有当公共接口与私有接口明显不同时,将API端点拆分为公共/私有才有意义。否则,您将面临代码冗余问题 在我们的项目中,我们提出了一个简单的解决方案,这似乎是许多人所期望的解决方案 我们在resolve方法上使用以下修饰符: #decorators.py

我已经看到了一些关于如何在石墨烯中实现许可系统的讨论,但除了这些讨论之外,还没有看到任何明确的实际结果。关于这一主题的一些讨论示例如下:


不幸的是,这些都不推荐在graphene中实现权限的首选方法。有人知道目前最好的做法是什么吗?

首先,只有当公共接口与私有接口明显不同时,将API端点拆分为公共/私有才有意义。否则,您将面临代码冗余问题

在我们的项目中,我们提出了一个简单的解决方案,这似乎是许多人所期望的解决方案

我们在
resolve
方法上使用以下修饰符:

#decorators.py
需要def权限(权限):
“”“根据每个方法检查权限。”“”
def包装装饰器(func):
def内部(cls、信息、*args、**kwargs):
如果检查权限(权限、信息上下文):
返回函数(cls,信息,**kwargs)
引发异常(“权限被拒绝”)
返回内部
返回包装装饰器
def check_权限(权限、上下文):
"""
帮助函数来解析权限。
权限可以是字符串“app\u name.perm\u codename”
或作为参数传递用户的可调用(lambda)函数:
示例:lambda(user):user.username.startswith('a'))
"""
如果可调用(权限):
如果没有权限(context.user):
返回错误
其他:
如果不是,则context.user.has_perm(权限):
返回错误
返回真值
您可以按如下方式使用此装饰器:

#schema.py
从…起decorators需要导入权限
类UserNode(DjangObjectType):
类元:
模型=用户
接口=(relay.Node,)
仅_字段=(
“id”、“名”、“姓”,
'电子邮件','用户名'
)
筛选器_字段={
“用户名”:[“准确”],
“id”:[“确切的”],
}
role=graphene.String(description=“用户在系统中的角色”)
@需要权限('我们的应用程序。一些\u perm')
def解析_角色(自我、信息、**kwargs):
如果['dev1','dev2']中的info.context.user.username:
返回“开发者”
如果info.context.user.is\u超级用户:
返回“admin”
如果info.context.user.is\u员工:
返回“工作人员”
返回“客人”
如果您没有此特定权限
我们的\u应用程序。某些\u perm
您将得到以下响应:

{
“错误”:[
{
“消息”:“权限被拒绝”,
“地点”:[
{
“行”:7,
“栏”:9
}
],
“路径”:[
“用户集”,
“边缘”,
0,
“节点”,
“角色”
]
},
{
“消息”:“权限被拒绝”,
“地点”:[
{
“行”:7,
“栏”:9
}
],
“路径”:[
“用户集”,
“边缘”,
1.
“节点”,
“角色”
]
}
],
“数据”:{
“用户集”:{
“边缘”:[
{
“节点”:{
“id”:“VXNlck5vZGU6MQ==”,
“用户名”:“user1”,
“角色”:空
}
},
{
“节点”:{
“id”:“VXNlck5vZGU6Mg==”,
“用户名”:“user2”,
“角色”:空
}
}
]
}
}
}
当您需要更具表现力的方式来检查权限时,例如 使用
语句检查多个权限,在
@required\u permission
装饰器中使用lambdas:


@需要许可(lambda u:u.has\u perm('app.perm1')或u.has\u perm('app.perm2'))
def解决某些问题1(自我、信息、**kwargs):
# ... 在这里做你的事
返回数据
@需要权限(lambda user:user.username.startswith('a'))
def解决某些问题2(自我、信息、**kwargs):
# ... 在这里做你的事
返回数据