DRF学习笔记(4)——权限控制


认证确定了你是谁
权限确定你能不能访问某个接⼝
限制确定你访问某个接⼝的频率

认证

自定义认证类
MyAuthentications.py

实现⾃定义的认证⽅案,要继承BaseAuthentication类并且重写.authenticate(self, request) ⽅法。如果认证成功,该⽅法应返回(user, auth)的⼆元元组,否则返回None。
不管是全局认证还是局部认证,都要使用到自定义认证类。

App\MyAuthentications.py
import itsdangerous
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from App.models import User
from App.util import token_confirm

class MyAuthentaion(BaseAuthentication):
    # 自定义的认证类必须实现authenticate,
    # 认证的规则,自己定义,成功返回一个二元组(user,value)
    def authenticate(self, request):
        # 1.获取token
        # token可以从请求的get参数中获取
        token = request.query_params.get('token')

        try:
            uid = token_confirm.confirm_validate_token(token,expiration=3600)  # expiration=3600  token3600秒之后过期
        except itsdangerous.exc.SignatureExpired as e: # token过期
            print(e)
            raise AuthenticationFailed("token过期")
        except:
            return None  # 认证不成功

        # 如果获取到uid
        # 查询数据库,获取用户信息
        try:
            user = User.objects.get(pk=uid)
        except:
            print("数据库访问错误")
            return None

        # print(user.__dict__)
        print("认证通过")
        # 如果找到了用户,认证成功
        return (user, None)
util.py

实现token的生成、验证、移除等操作。

from itsdangerous import URLSafeTimedSerializer as utsr
import base64

class Token:
    def __init__(self, security_key):
        self.security_key = security_key
        self.salt = base64.encodebytes(security_key.encode('utf8'))
    # 生成token
    def generate_validate_token(self, username):
        serializer = utsr(self.security_key)
        res = serializer.dumps(username, self.salt)
        print(serializer)
        return res
    # 验证token
    def confirm_validate_token(self, token, expiration=3600):
        serializer = utsr(self.security_key)
        return serializer.loads(token, salt=self.salt, max_age=expiration)
    # 移除token
    def remove_validate_token(self, token):
        serializer = utsr(self.security_key)
        print(serializer.loads(token, salt=self.salt))
        return serializer.loads(token, salt=self.salt)


token_confirm = Token("sdkfksdfkl*(()872873784387#@#@94.,.,xcv,ksdkfi$#$#")    # 定义为全局变量
全局认证
  • setting设置
REST_FRAMEWORK = {
 'DEFAULT_AUTHENTICATION_CLASSES': (
	 'App.authentications.MyAuthentication', 
 )
}
  • 视图函数获取token
    获取的token是所有的user公用的token
views.py
class UserToken(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def get(self,request):
        # 产生token
        user = User.objects.first()
        # 使用用户id生成token
        token = token_confirm.generate_validate_token(user.id)
        # 把token返回给客户端
        return Response({'token':token})

path('user/<int:pk>/',views.UserInfoView.as_view(),name='user'),
path('token/',views.UserToken.as_view(),name='usertoken'),
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

局部认证
  • 在视图函数中写认证函数
views.py
class UserInfoView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # 局部认证,只针对当前类
    authentication_classes = (MyAuthentaion,)
    lookup_field = 'pk'
    def get(self,request,pk):
        obj = self.get_object()  # 获取对象
        us = UserSerializer(instance=obj)  # 序列化
        return Response(us.data)

权限控制

权限控制可以限制⽤户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()⽅法前,会先进行视图访问权限的判断。
  • 在通过get_object()获取具体对象时,会进行对象访问权限的判断
    权限针对模型或者视图对象
全局权限控制
  • 在setting中设置DEFAULT_PERMISSION_CLASSES
  • 限制访问
    最简单的权限是允许通过身份验证的用户访问,并拒绝未经身份验证的用户访问。这对应于 REST framework 中的 IsAuthenticated 类。
    稍微宽松的权限会允许通过身份验证的用户完全访问,而未通过身份验证的用户只能进行只读访问。这对应于 REST framework 中的 IsAuthenticatedOrReadOnly 类。
    AllowAny 允许所有用户
    IsAuthenticated 仅通过认证的用户
    IsAdminUser 仅管理员用户
    IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
  • 无限制访问
'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)
自定义权限控制
App\MyPerssions.py
class MyPermisson(BasePermission):
    # 对视图授权
    def has_permission(self, request, view):
        print("权限限制")
        # 返回True就是有权限
        # 返回False就是没权限
        # return False

        # 认证通过就有权限
        return request.user and isinstance(request.user,User)
views.py
class UserInfoView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # 局部认证,只针对当前类
    authentication_classes = (MyAuthentaion,)
    # 授权
    permission_classes = (MyPermisson,)
    lookup_field = 'pk'
    def get(self,request,pk):
        obj = self.get_object()  # 获取对象
        us = UserSerializer(instance=obj)  # 序列化
        return Response(us.data)

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值