Vue + Django 2.0.6 学习笔记 8.4 drf的权限验证

目前已经完成了用户注册,登录验证和商品收藏的功能。但是还不够。还要有用户权限验证

比如 此收藏是否为用户自己的收藏。登录的用户是否有权限更改其他用户的收藏等

涉及到的库:

https://www.django-rest-framework.org/api-guide/permissions/

这两货不一样。 Auth是用于用户登录验证,Perm使用于用户权限验证

Permissions下这些验证库

 

AllowAny:不管有没有权限都可以访问。

IsAuthenticated: 判断是否已经登录

IsAdminUser:判断用户是否是一个管理员。根据此字段 user.is_staff

判断是否登录:(未登录访问时抛401错误给前端)

from utils.permissions import IsOwnerOrReadOnly

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    用户收藏功能
    """
    permission_classes = (IsAuthenticated,)

自定义权限验证Custom permissions

https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

IP白名单检测:

from rest_framework import permissions

class BlacklistPermission(permissions.BasePermission):
    """
    Global permission check for blacklisted IPs.
    """

    def has_permission(self, request, view):
        ip_addr = request.META['REMOTE_ADDR']
        blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
        return not blacklisted

是否是用户本人,否则只读的例子:

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Instance must have an attribute named `owner`.
        return obj.owner == request.user

拿到教程项目中使用的例子

# 新建 utils/permissions.py

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

# 重写BasePermission中的has_object_permission函数
# 用来判定所要操作对象的user字段是否等于request.user字段

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.user == request.user

使用该自定义Permission

# users_operation/views.py

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    用户收藏功能
    """
# ---------------------------------------->这里
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)

这样做完之后 如果要删除或修改的时候 会要求验证权限的。

不过这里也有问题,不能让某一用户获取到所有的收藏信息,其实也没必要全部获取到,获取到自己的不就完事了 。

所以需要重写get_queryset函数

    def get_queryset(self):
        return UserFav.objects.filter(user=self.request.user)

类中配置queryset变量的参数可以删掉了

然后有一个小bug

要将这里改成self.user.username 否则xadmin获取某一用户收藏时会报错

class UserFav(models.Model):
    """
    用户收藏
    """
    user = models.ForeignKey(User, verbose_name=u'用户', on_delete=models.CASCADE)
    goods = models.ForeignKey(Goods, verbose_name=u'商品', on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加时间')

    class Meta:
        verbose_name = u'用户收藏'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
# 这里
        return self.user.username

之前我们将JWT验证放在了全局的settings.py中。这会有问题

不是每一个页面都需要验证。

所以我们需要将全局的JWT验证放到部分需要用户验证的view中

注释掉

在用户收藏中做示例

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    用户收藏功能
    """
#  ------------------------------------------------------> 这个是用于DEF控制台的测试登录用
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

默认情况下 

前端用户是通过表ID来读取相应字段。但是ID字段是数据库自动递增生成的。 但是鬼知道这些ID是对应哪个数据

所以 收藏的话 正常是希望通过商品id就能够访问到

所以需要这么干:

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    用户收藏功能
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    serializer_class = UserFavSerializer
# 这里
    lookup_field = "goods_id"
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

这节 主要说的是 用户的权限验证,自定义queryset对象,局部JWT验证和generic views字段关联

https://www.django-rest-framework.org/api-guide/generic-views/#genericapiview

完结 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@凌晨三点半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值