django drf使用问题

是不是使用了drf和simplejwt进行登录验证,就无法使用原生的权限控制了,比如permission_requied,我这里使用了以后提示没有登录,但是我的session表里已经有token了,request.user里也有用户名字了

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在Django和DRF中,权限控制可以通过多种方式实现,如使用permission_required、自定义permission class、使用authentication class等。在使用DRF和SimpleJWT进行验证时,可以通过配置DEFAULT_AUTHENTICATION_CLASSESDEFAULT_PERMISSION_CLASSES来指定需要使用哪些配置类。但是请注意,权限验证和身份验证是两个不同的概念。身份验证通常用于验证用户是否已登录,而权限验证用于验证用户是否具有执行特定操作所需的权限。

在使用DRF和SimpleJWT进行身份验证时,由于JWT令牌已经包含了用户信息,所以直接通过request.user获取。因此,使用permission_required进行权限验证时可能会失败,因为它的实现方式需要从session或cookie中获取用户id或其他信息,而不是从JWT令牌中获取。

解决方案是使用DRF提供的permission_classes来指定你自己的权限验证类,比如IsAuthenticatedIsAdminUser等。下面是一个简单的示例代码:

from rest_framework import permissions

class MyPermission(permissions.BasePermission):
    message = 'You do not have permission to perform this action.'

    def has_permission(self, request, view):
        if request.user.is_authenticated and request.user.is_staff:
            return True
        return False


class MyView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        return Response({'message': 'Hello, world!'})

在上面的代码中,我们自定义了一个MyPermission类,它继承自DRF的BasePermission类并覆盖了has_permission方法。在这个方法中,我们检查request.user是否为认证用户且是管理员。如果是,则说明该用户具有执行此行动所需的权限,否则将返回错误消息。最后,我们将该权限类分配给我们需要保护的视图。

请注意,在使用DRF和SimpleJWT进行验证时,确保在settings.py中正确配置了DEFAULT_AUTHENTICATION_CLASSESDEFAULT_PERMISSION_CLASSES。例如:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

以上配置将使用SimpleJWT进行验证,并将DRF提供的IsAuthenticated权限类分配给所有视图。如果你需要更高级的权限验证功能,如基于角色的访问控制(RBAC),可以使用第三方库,如django-guardiandjango-rules等。

希望这个答案可以解决你的问题。
如果我的回答解决了您的问题,请采纳!

看看你的客户端怎么判断的,既然已经有session了,有没有返回客户端success

该回答引用ChatGPT

如有疑问,可以回复我!

Django REST framework(DRF)和Django自带的权限系统是可以共存的。不过,由于DRF和Django的会话和身份验证机制有所不同,所以在使用DRF和SimpleJWT进行登录验证时,需要注意一些事项。

首先,Django的permission_required装饰器在处理基于session的验证时表现良好,但在处理基于token的验证时可能出现问题。DRF和SimpleJWT使用的是基于token的验证方式,因此,如果要在DRF中使用原生的权限控制,建议使用DRF自带的权限系统。

DRF的权限系统提供了一些内置的类,例如IsAuthenticated、IsAdminUser等,你可以在视图中指定权限类。例如:


from rest_framework.permissions import IsAuthenticated

class MyApiView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        # ...


如果需要使用Django的permission_required装饰器,你需要确保在使用DRF和SimpleJWT时,同时启用session验证。在你的项目的settings.py文件中,将SessionAuthentication添加到REST_FRAMEWORK的配置中:


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    # ...
}

然后,确保在使用permission_required时,已经登录并具有相应的权限。例如:


from django.contrib.auth.decorators import permission_required

@permission_required('myapp.view_mymodel')
def my_view(request):
    # ...

参考GPT和自己的思路,在Django Rest Framework (DRF) 中,使用Simple JWT进行身份验证,可以与DRF的权限系统集成。这意味着您仍然可以使用DRF的原生权限控制,比如 permission_required。但是,您需要在视图中指定要使用的身份验证类和权限类,例如:

from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication

class MyView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    # Your view code here

上述示例中,我们在视图类中指定使用JWT身份验证,并使用 IsAuthenticated 权限类进行权限控制。

此外,如果您已经在request.user中看到了用户信息,那么在视图中也可以使用 @login_required 装饰器来限制未登录用户访问视图,例如:

from django.contrib.auth.decorators import login_required
from rest_framework.decorators import api_view

@api_view(['GET'])
@login_required
def my_view(request):
    # Your view code here

在上述示例中,我们使用了 @login_required 装饰器来限制未登录用户访问该视图。

请注意,如果您同时使用了JWT身份验证和Django的会话(session),则需要确保在使用JWT时禁用CSRF检查,因为JWT不使用Django的CSRF机制。可以通过将'rest_framework.authentication.SessionAuthentication'从您的身份验证类中删除来实现这一点,例如:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ],
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.OrderingFilter',
    ],
    'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata',
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 10,
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/day',
        'user': '100/day'
    }
}

# Remove 'rest_framework.authentication.SessionAuthentication' from the authentication classes
REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'].remove('rest_framework.authentication.SessionAuthentication')

在上述示例中,我们将'rest_framework.authentication.SessionAuthentication'从身份验证类中删除。

回答不易,还请采纳!!!

参考GPT和自己的思路:Django Rest Framework (DRF) 和 Simple JWT 都提供了自己的认证和权限控制方式,但是它们并不会影响 Django 的原生权限控制机制,比如 permission_required 装饰器。

如果你的应用中使用了 DRF 和 Simple JWT 进行登录验证,并且你希望使用 Django 的原生权限控制机制,你可以按照以下步骤操作:

1 在 settings.py 中配置 DRF 和 Simple JWT 的认证类和权限类,同时也需要配置 Django 的认证类和权限类。例如:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
]


2 在视图函数中使用 permission_required 装饰器进行权限控制,例如:

from django.contrib.auth.decorators import permission_required

@permission_required('myapp.view_mymodel')
def my_view(request):
    # your code here


在上面的示例中,permission_required 装饰器会检查用户是否具有 myapp.view_mymodel 权限。如果用户已经登录并且具有该权限,请求将被允许;否则,请求将被拒绝,并返回 HTTP 403 错误。

请注意,如果你使用了 DRF 和 Simple JWT 进行登录验证,那么 request.user 并不会包含 Django User 模型的实例。相反,你可以使用 request.user.id 来获取用户的 ID,然后使用 Django 的认证系统获取用户实例。例如:

from django.contrib.auth import get_user_model

User = get_user_model()

def my_view(request):
    user_id = request.user.id
    user = User.objects.get(id=user_id)
    # your code here


希望以上信息能够帮助你解决问题。

参考GPT和自己的思路:

使用DRF和SimpleJWT进行登录验证后,你仍然可以使用原生的权限控制,如permission_required。只要确保在视图中将权限类指定为需要使用的权限类即可。

在使用SimpleJWT时,它会将用户验证的结果存储在用户的JWT Token中,并存储在请求的头部中,request.user里存储的是用户对象,而不是用户名字。如果你想使用原生的session表,并且在request.user中获得用户名字,你可以考虑使用django.contrib.sessions.middleware.SessionMiddleware。但是使用SessionMiddleware需要核对您登出后编写其他代码以正确处理你的JWT Token。

使用DRF和SimpleJWT进行身份验证时,您需要使用DRF提供的权限系统来控制访问权限。这是因为,DRF提供的权限系统已经集成到身份验证流程中,而原生的权限控制不支持JWT身份验证。

要使用DRF的权限系统,请使用permissions模块中的适当权限类,例如IsAuthenticated和IsAdminUser等。您可以在视图或视图集中设置这些权限类,以限制对特定端点的访问。

以下是一个使用DRF权限系统的示例视图集合代码:

from rest_framework import viewsets, permissions
from .models import MyModel
from .serializers import MyModelSerializer

class MyModelViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

在上面的代码中,我们设置了一个MyModelViewSet视图集合,并将其permission_classes属性设置为IsAuthenticated。这将限制只有经过身份验证的用户才能访问MyModel的所有端点。

请注意,您需要通过将JWT令牌附加到请求头来进行身份验证,而不是通过使用session表中的cookie。因此,即使您的session表中有令牌,您也需要在请求头中提供它。

例如,使用curl进行身份验证和访问MyModelViewSet端点的示例命令如下:

curl -H "Authorization: Bearer <your_token_here>" http://localhost:8000/my-models/

请将替换为您的JWT令牌。