我见过许多关于如何在石墨烯中实施许可制度的讨论,但除了这些讨论之外,我没有看到任何明确的实际结果。关于这一专题的一些讨论实例如下:
不幸的是,所有这些都不推荐在石墨烯中实现权限的首选方法。有没有人知道目前做这件事的最佳做法是什么?
发布于 2019-10-25 19:47:06
首先,只有当公共接口与私有接口有很大区别时,才能将API端点拆分为公共/私有端点。否则,您将面临代码问题中的冗余。
在我们的项目中,我们提出了一个简单的解决方案,它似乎被许多人认为是理想的解决方案。
我们在resolve方法上使用了以下修饰器:
# decorators.py
def permission_required(permission):
""" Checking permissions on per method basis. """
def wrapped_decorator(func):
def inner(cls, info, *args, **kwargs):
if check_permission(permission, info.context):
return func(cls, info, **kwargs)
raise Exception("Permission Denied.")
return inner
return wrapped_decorator
def check_permission(permission, context):
"""
Helper function to resolve permissions.
Permission can be a string "app_name.perm_codename"
or callable (lambda) function with user passed as an argument:
example: lambda(user): user.username.startswith('a')
"""
if callable(permission):
if not permission(context.user):
return False
else:
if not context.user.has_perm(permission):
return False
return True您可以如下所示使用此装饰器:
# schema.py
from . decorators import permission_required
class UserNode(DjangoObjectType):
class Meta:
model = User
interfaces = (relay.Node,)
only_fields = (
'id', 'first_name', 'last_name',
'email', 'username'
)
filter_fields = {
'username': ['exact'],
'id': ['exact'],
}
role = graphene.String(description="User's role in the system.")
@permission_required('our_app.some_perm')
def resolve_role(self, info, **kwargs):
if info.context.user.username in ['dev1', 'dev2']:
return "developer"
if info.context.user.is_superuser:
return "admin"
if info.context.user.is_staff:
return "staff"
return "guest"如果您没有这个特殊权限our_app.some_perm,您将得到以下响应:
{
"errors": [
{
"message": "Permission Denied.",
"locations": [
{
"line": 7,
"column": 9
}
],
"path": [
"userSet",
"edges",
0,
"node",
"role"
]
},
{
"message": "Permission Denied.",
"locations": [
{
"line": 7,
"column": 9
}
],
"path": [
"userSet",
"edges",
1,
"node",
"role"
]
}
],
"data": {
"userSet": {
"edges": [
{
"node": {
"id": "VXNlck5vZGU6MQ==",
"username": "user1",
"role": null
}
},
{
"node": {
"id": "VXNlck5vZGU6Mg==",
"username": "user2",
"role": null
}
}
]
}
}
}当您需要更有表现力的方式来检查权限时,例如当使用or语句检查多个权限时,请在@required_permission装饰器中使用lambdas:
@permission_required(lambda u: u.has_perm('app.perm1') or u.has_perm('app.perm2'))
def resolve_something1(self, info, **kwargs):
# ... do your stuff here
return data
@permission_required(lambda user: user.username.startswith('a'))
def resolve_something2(self, info, **kwargs):
# ... do your stuff here
return datahttps://stackoverflow.com/questions/58092792
复制相似问题