如何通过Token认证实现POST请求权限校验?Django场景及报错解决
解决方案
一、POST请求身份认证实现
你当前的过滤后端仅对查询类请求(get/list/retrieve)生效,create类请求不会触发查询过滤逻辑,可选用以下任意一种方案实现权限控制:
方案1:序列化器层实现(推荐)
修改ArticleImageSerializer,自动填充作者字段+校验文章归属权:
class ArticleImageSerializer(serializers.ModelSerializer): class Meta: model = ArticleImage fields = ('id','image','article') read_only_fields = ('author',) # 禁止前端传入作者字段,避免身份冒用 # 单独校验article字段 def validate_article(self, value): # value为DRF自动反序列化得到的Article对象,无需自行查库 if value.author != self.context['request'].user: raise serializers.ValidationError("你没有权限为该文章添加图片资源") return value # 创建时自动填充当前登录用户为作者 def create(self, validated_data): validated_data['author'] = self.context['request'].user return super().create(validated_data)
方案2:视图层实现
直接修改ArticleImageViewSet,在创建逻辑执行前做校验:
class ArticleImageViewSet(viewsets.ModelViewSet): permission_classes = (IsAuthenticated,) queryset = ArticleImage.objects.all() serializer_class = ArticleImageSerializer filter_backends = [ArticleFilterBackend] def perform_create(self, serializer): article = serializer.validated_data['article'] if article.author != self.request.user: raise serializers.ValidationError("无权操作该文章") # 自动保存当前用户为作者,忽略前端传入的author参数 serializer.save(author=self.request.user)
以上两种方案均可以实现两个需求:仅允许为自己名下的文章添加图片;禁止用户冒用他人身份提交请求。
二、UUID报错问题修复
报错'Article object (xxx)” is not a valid UUID'的根因是:你在自定义validate方法中,错误地将DRF已经自动反序列化完成的Article对象当成UUID字符串,传入Article.objects.get(id=xxx)做二次查询,此时Article对象会被转为字符串格式传入UUID字段校验,触发格式错误。
修复方法:
直接使用serializer.validated_data中已经反序列化完成的Article对象做权限校验即可,无需自行根据ID查库,参考上面提供的validate_article写法即可。
内容的提问来源于stack exchange,提问作者user14491987
相关产品推荐
相关产品推荐

