python - Django:ViewSets 不接受登录要求,导致 SessionAuthentication 无用

标签 python django authentication token

我在使用 DRF SessionAuthentication 和定义为 ModelViewSets 的 View 时遇到问题。 “LoginRequiredMixin”在泛型 View 中工作得很好,但我真的不喜欢那些,因为它们要求我手动定义所有 url 并按正确的顺序设置它们。当 ViewSets 允许您更整齐地定义路线时,这非常乏味。

我尝试按照 Django 文档 authentication login() 使用“@login_required”装饰器,但它不接受它。已尝试在我的 ViewSet 中指定authentication_class SessionAuthentication 但无济于事,遵循这些帖子:

当前 FooBar_views.py 文件。到目前为止,我确保用户通过身份验证的唯一方法是检查其 http 请求 header 中提供的 JWT。

foobar_vews.py 与 ViewSets

# @login_required not being accepted when imported
class FooBarViewSet(viewsets.ModelViewSet):
    """
    Foo Bar ViewSet calling various serializers depending on request type (GET, PUT etc.)
    """

    # Trying to filter FooBars list by status: Exluding unwanted ones
    queryset = FooBar.objects.exclude(status__name = 'SOLD').exclude(status__name = 'DELETED').order_by('id').reverse()

    # mapping serializer into the action
    serializer_classes = {
        'list': FooBarIndexSerializer,
        'retrieve': FooBarDetailsSerializer,
        'create': FooBarCreateSerializer,
    }

    # Your default serializer
    default_serializer_class = FooBarIndexSerializer

    def get_serializer_class(self):
        """
        Method to detect request type (GET, PUT etc.) and select corresponding serializer.
        """
        return self.serializer_classes.get(self.action, self.default_serializer_class)

    # TODO: Move this to the permissions.py file?
    def get_permissions(self):
        """
        Method to apply permissions depending on request type (GET, PUT etc.)
        """
        if self.request.method == 'GET':
            return [permissions.DjangoModelPermissionsOrAnonReadOnly()]
        elif self.request.method == 'POST':
            return [permissions.IsAuthenticated(), IsArtist()]
        else:  # PUT, PATCH, DELETE
            return [permissions.IsAuthenticated(), IsOwner()]

如果使用泛型 View ,我需要定义等效项。可以看出,我不需要添加任何“isAuthenticated”权限类,因为“LoginRequiredMixin”通过检查 sessionId 和 CSRFToken 来检查用户是否已登录。

问题在这里,我需要在url.py文件中手动定义所有对应的url。这是乏味且令人困惑的,因为 FooBarListView 和 FooBarCreateView 通常应该是相同的 url,但请求不同,例如 GET 和 POST。

带有通用 View 的foobar_vews.py

class FooBarListView(LoginRequiredMixin, ListAPIView):
   queryset = FooBar.objects.all()
   serializer_class = FooBarIndexSerializer

class FooBarDetailView(LoginRequiredMixin, RetrieveAPIView):
   queryset = FooBar.objects.all()
   serializer_class = FooBarDetailsSerializer

# TODO: Voir pour passer aux modelViews
class FooBarCreateView(LoginRequiredMixin, CreateAPIView):
   queryset = FooBar.objects.all()
   serializer_class = FooBarCreateSerializer
   permission_classes = [IsOwner]

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

class FooBarUpdateDestroyView(LoginRequiredMixin, UpdateDestroyAPIView):
   queryset=FooBar.objects.all()
   serializer_class = FooBarDetailsSerializer
   permission_classes = [IsOwner]

因此,有没有办法检查用户是否在 ViewSets 中被盗,或者我是否被迫使用 JWT 身份验证系统,在客户端保存 token (这是否安全?),并从前端确保对于每个请求,用户都在 header 中提供这些内容?

任何关于如何在 ViewSets 中实现这一点的帮助将不胜感激。

最佳答案

第一件事:您必须了解装饰器只能在函数上使用,您不能按照您使用它的方式在基于类的 View 中使用它。所以很明显 django View 集不会接受 @login_required 装饰器。

那么问题是,你能修饰类的方法吗?答案是,。 这是 django 文档 Decorating the class ,它说,

To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class.

A method on a class isn’t quite the same as a standalone function, so you can’t just apply a function decorator to the method – you need to transform it into a method decorator first. The method_decorator decorator transforms a function decorator into a method decorator so that it can be used on an instance method. For example:

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

关于python - Django:ViewSets 不接受登录要求,导致 SessionAuthentication 无用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61656146/

相关文章:

python - 如何将 python-dev 包含在 buildroot 中?

python - 如何获得用户选择的 radio 选项? Django

使用 NTLM 进行 Python Mechanize 时出现 AttributeError : HTTPResponse instance has no attribute '__iter__'

python - TensorFlow:将输入发送到导出的模型

Django:获取最新的不同对象

python - django 管理面板对表单集中的每个表单进行编号

php - 使用 PDO 从 MySQL 获取用户信息时出错

java - Facebook 登录方法 Onload

python - 使用 Mechanize 进行 Python 抓取脚本的 HTTP 错误 401

python - 将函数与 numpy 数组的每个元素集成为集成限制