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

2020-10-14 23:41:42 +08:00
 knight3r

老哥们,我有一个需求就是我有一个 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')
2308 次点击
所在节点    Django
5 条回复
wuwukai007
2020-10-15 07:57:48 +08:00
写个新的类继承一下,里面放 post 接口,permission_clasa=(),不就好了,
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
2020-10-15 11:04:55 +08:00
@wuwukai007 额 permission 的话可以写装饰器解决,可是 authentication 就不行
knight3r
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
2020-11-15 19:47:14 +08:00
这个实现还是比较直观的,直接做个 permission factory 就 ok,

代码直接参考 CRUD permission,然后把 self.action 扔进去判断就可以。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/715036

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX