首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Django REST框架的RBAC

使用Django REST框架的RBAC
EN

Stack Overflow用户
提问于 2018-11-29 22:58:28
回答 1查看 813关注 0票数 2

关于我应该使用什么来集成RBAC和DRF有什么建议吗?我看过django-rest-framework-roles和django-guardian,但它们看起来都不太有前途。您的反馈将非常感谢。提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2021-05-29 16:27:35

我所做的是为UsersGroupsPermissions创建端点,并将DjangoModelPermissionsTokenAuthentication结合使用。

您可以将User模型覆盖为abstractUser,也可以按原样使用它。

UsersPermissionsGroup创建序列化程序。

我个人遵循了这种方法:

rbac/api/viewsets.py

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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_frameworkrest_framework.token

settings.py:

代码语言:javascript
复制
...
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',
    ),
}

如下所示,您的端点应该如下所示:

接口/根:

代码语言:javascript
复制
{
    "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:

代码语言:javascript
复制
{
        "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本身创建的组。

接口/组:

代码语言:javascript
复制
[
    {
        "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这个话题的答案很少。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53541814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档