关于我应该使用什么来集成RBAC和DRF有什么建议吗?我看过django-rest-framework-roles和django-guardian,但它们看起来都不太有前途。您的反馈将非常感谢。提前谢谢。
发布于 2021-05-29 16:27:35
我所做的是为Users、Groups和Permissions创建端点,并将DjangoModelPermissions与TokenAuthentication结合使用。
您可以将User模型覆盖为abstractUser,也可以按原样使用它。
为Users、Permissions和Group创建序列化程序。
我个人遵循了这种方法:
rbac/api/viewsets.py
from rest_framework import serializers
from customuser.models import CustomUser
from django.contrib.auth.models import Group, Permission
from rest_framework.authtoken.models import Token
class CustomUserSerializer(serializers.ModelSerializer):
""" Custom User for authentication """
class Meta:
model = CustomUser
read_only_fields = ["is_superuser"]
fields = [
"id",
"is_superuser",
"username",
"first_name",
"last_name",
"email",
"password",
"is_staff",
"is_active",
"date_joined",
"last_login",
"is_admin",
"is_insurer",
"groups",
]
# hash password
def create(self, validated_data):
user = super(CustomUserSerializer, self).create(validated_data)
user.set_password(validated_data['password'])
user.save()
return user
class PermissionSerializer(serializers.ModelSerializer):
""" Add permissions serializer """
class Meta:
model = Permission
fields ='__all__'
class GroupSerializer(serializers.HyperlinkedModelSerializer):
""" Add group serializer """
url = serializers.HyperlinkedIdentityField(view_name="customuser:groups-detail")
permissions = PermissionSerializer(many=True)
class Meta:
model = Group
fields = ['url', 'name', 'permissions']对于rbac/api/viewsets.py:
from rest_framework import viewsets
from customuser.models import CustomUser
from django.contrib.auth.models import Group, Permission
from .serializers import CustomUserSerializer, GroupSerializer, PermissionSerializer
from django.utils.decorators import method_decorator
from rest_framework.permissions import IsAuthenticated, DjangoModelPermissions
from rest_framework.authentication import TokenAuthentication
class CustomUserViewSet(viewsets.ModelViewSet):
queryset = CustomUser.objects.all()
serializer_class = CustomUserSerializer
# remove these two lines to remove auth
authentication_classes = [TokenAuthentication]
authentication_classes = [IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows view/create/edit/delete groups.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
# remove these two lines to remove auth
authentication_classes = [TokenAuthentication]
authentication_classes = [IsAuthenticated]
class PermissionViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Permission.objects.all()
# remove these two lines to remove auth
authentication_classes = [TokenAuthentication]
authentication_classes = [IsAuthenticated]如果您还不知道,构建django的Group类与Permission类有一个manyToMany关系。因此,您应该在GroupSerializer类中遵循相同的方法。实例化组序列化程序类中的权限序列化程序类并传递many=True。
这样,当您创建一个组时,您将能够从api传递对它的权限。
在我称为rbac的应用程序中,您可以创建另一个url.py文件,并添加以下代码:
rbac/url.py:
from django.urls import path, include
from .api.viewsets import CustomUserViewSet, GroupViewSet, PermissionViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('customuser', CustomUserViewSet, basename='customuser')
router.register('groups', GroupViewSet, basename='groups')
router.register('permission', PermissionViewSet, basename='permission')
app_name='customuser'
urlpatterns = [
path('', include(router.urls)),
](别忘了在主url.py中包含()这个url.py)
如果你想通过令牌认证你的用户,你应该在你的settings.py中添加你的rbac应用,rest_framework和rest_framework.token。
settings.py:
...
INSTALLED_APPS = [
...
'rbacr',
'rest_framework',
'rest_framework.authtoken'
]
# if you created a customUser model as AbstractUSer
AUTH_USER_MODEL = 'rbac.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissions',<==== SET THE CORE DJANGO PERMISSION INSTEAD
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}如下所示,您的端点应该如下所示:
接口/根:
{
"customuser": "http://127.0.0.1:8000/api/customuser/",
"groups": "http://127.0.0.1:8000/api/groups/",
"permission": "http://127.0.0.1:8000/api/permission/"
}api/customuser:
{
"id": 2,
"is_superuser": false,
"username": "anyname",
"first_name": "",
"last_name": "",
"email": "",
"password": "pbkdf2_sha256$260000$gD........",
"is_staff": true,
"is_active": true,
"date_joined": "2021-05-24T02:16:00Z",
"last_login": "2021-05-26T02:57:30.215345Z",
"groups": [
3, <====
4 <====
]
}这些是使用drf api本身创建的组。
接口/组:
[
{
"url": "http://127.0.0.1:8000/api/groups/1/",
"name": "admin_group",
"permissions": [
{
"id": 21,
"name": "Can add user",
"codename": "add_customuser",
"content_type": 6
},
{
"id": 25,
"name": "Can view user",
"codename": "can_view_user",
"content_type": 6
},
{
"id": 22,
"name": "Can change user",
"codename": "change_customuser",
"content_type": 6
},
{
"id": 23,
"name": "Can delete user",
"codename": "delete_customuser",
"content_type": 6
},
{
"id": 24,
"name": "Can view user",
"codename": "view_customuser",
"content_type": 6
}
]
},
{
"url": "http://127.0.0.1:8000/api/groups/2/",
"name": "insurer_group",
"permissions": [
{
"id": 25,
"name": "Can view user",
"codename": "can_view_user",
"content_type": 6 <======= CUSTOM USER ID
}
]
},
{
"url": "http://127.0.0.1:8000/api/groups/3/",
"name": "whatever_group",
"permissions": [] <===== ONLY VIEW --- NEED A SMALL CHANGE TO REMOVE VIEW
}
]对于api/权限,将显示所有类/表的所有权限。
使用这种方法,您可以创建具有自定义权限的组,并将它们分配给用户,如第一个端点所示。每个组在customuser端点中都有一个id,然后,如果需要,您可以添加一个脚本来修改它们,而不是显示名称。这样,您将能够扩展要使用的管理员,并为每个组分配权限,并向一个用户添加多个组。在我看来,组也可以被视为角色。
我建议你检查一下:
1- DjangoModelPermissions 2- Django Group and Permissions
我是django的中级,如果你对这个问题有更好的答案,我将不胜感激。因为关于django这个话题的答案很少。
https://stackoverflow.com/questions/53541814
复制相似问题