V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
knight3r
V2EX  ›  Django

对同一 viewset 的不同 action 方法不同的 authenticaltion 是否可行?

  •  
  •   knight3r · 2020-10-14 23:41:42 +08:00 · 2048 次点击
    这是一个创建于 1260 天前的主题,其中的信息可能已经有所发展或是发生改变。

    老哥们,我有一个需求就是我有一个 viewset 我想使用 post 方法的时候使用 JWT 认证,而使用 list 和 retrieve 方法的时候不使用认证,各位老哥有办法吗?我用过 @authentication_class()这个装饰器,但是无效啊

    class UserViewSet(CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
        queryset = UserProfile.objects.all()
        #authentication_classes = [JwtAuthorizationAuthentication,]
    
        def get_serializer_class(self):
            if self.action == 'create':
                return UserRegisterSerializer
            else:
                return UserLoginSerializer
    
        def create(self, request, *args, **kwargs):
            return Response('ok')
    
        def retrieve(self, request, *args, **kwargs):
            print(f'1{self.authentication_classes}')
            return Response('ok')
    
    5 条回复    2020-11-15 19:47:14 +08:00
    wuwukai007
        1
    wuwukai007  
       2020-10-15 07:57:48 +08:00 via Android
    写个新的类继承一下,里面放 post 接口,permission_clasa=(),不就好了,
    Neo10373
        2
    Neo10373  
       2020-10-15 09:05:28 +08:00
    create,retrieve 等默认 action 是不行的, 会自动使用 UserViewSet 的 authentication_classes,

    1. 要么关闭视图类属性的 authentication_classes, 每个 action 内自己使用 JwtAuthorizationAuthentication 进行认证
    2. 要么去掉 CreateModelMixin, RetrieveModelMixin, 自己写 action
    ```
    @action(detail=False, authentication_classes=(JwtAuthorizationAuthentication, ))
    def my_create(self, request, *args, **kwargs):

    @action(detail=True, authentication_classes=())
    def my_retrieve(self, request, *args, **kwargs):
    ```
    knight3r
        3
    knight3r  
    OP
       2020-10-15 11:04:55 +08:00
    @wuwukai007 额 permission 的话可以写装饰器解决,可是 authentication 就不行
    knight3r
        4
    knight3r  
    OP
       2020-10-15 11:08:53 +08:00
    @Neo10373 哈哈,谢谢老哥,这个方法是可以,但是我想使用 Viewset 和 Mixin 带给我的便利,那个 permission 的我自己写过一个装饰器可以对 create 和 retrieve 方法管用,但是不知道为什么写成 authentication 那样就不行了啊
    ```[python]
    from functools import update_wrapper

    def auth_wrapper(*authentications, validate_auth=True):
    def decorator(func):
    def wrapper(self, request, *args, **kwargs):
    self.authentication_classes=authentications
    print(self.authentication_classes)
    if validate_auth:
    print(f'request1:{request.user}')
    self.perform_authentication(request)
    print(f'request2:{request._user}')
    # print(type(self.perform_authentication(request)))
    print('进来了')
    return func(self, request, *args, **kwargs)
    return update_wrapper(wrapper, func)
    return decorator

    def permission_wrapper(*permissions, validate_perm=True):
    def decorator(func):
    def wapper(self, request, *args, **kwargs):
    self.permission_classes=permissions
    if validate_perm:
    self.check_permissions(request)
    return func(self, request, *args, **kwargs)
    return update_wrapper(wapper, func)
    return decorator



    ```
    freakxx
        5
    freakxx  
       2020-11-15 19:47:14 +08:00
    这个实现还是比较直观的,直接做个 permission factory 就 ok,

    代码直接参考 CRUD permission,然后把 self.action 扔进去判断就可以。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5489 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 09:01 · PVG 17:01 · LAX 02:01 · JFK 05:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.