DAY99 - Rest Framework(四)- 认证组件和权限组件

一、认证组件

1.使用

# 模型层
class User(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)

class UserToken(models.Model):
    user = models.OneToOneField(to=‘User‘)
    token = models.CharField(max_length=64)
#myAuth.py
from app01 import models
from rest_framework.exceptions import APIException
from rest_framework.authentication import BaseAuthentication

class Auth(BaseAuthentication):
    def authenticate(self,request):
        # 包装后的request对象,请求来的所有东西都能拿出来
        token = request.GET.get(‘token‘)
        ret = models.UserToken.objects.filter(token=token).first()
        # 如果有值,说明登录过了,而且带的随机字符串也是正确的
        # 如果认证通过,需要返回东西,如果认证不通过,要抛异常
        if ret:
            # 返回一个元组如果返回None,就会是一个匿名用户
            return ret.user,ret
        else:
            # 如果没有值,抛异常
            raise APIException(‘您没有登录‘)
from app01.mySer import *
import uuid

# 登陆视图
class Login(APIView):
    def post(self, request):
        response = {‘status‘: 200, ‘msg‘: ‘登录成功‘}
        name = request.data.get(‘name‘)
        pwd = request.data.get(‘pwd‘)
        user = models.User.objects.filter(name=name, pwd=pwd).first()
        if user:
            token = uuid.uuid4()
            # 登陆成功后,存入token表
            models.UserToken.objects.create(token=token, user=user)
            response[‘token‘] = token
        else:
            response[‘status‘] = 201
            response[‘msg‘] = ‘添加失败‘
        return JsonResponse(response, safe=False)
# 局部使用,在所需的视图里局部使用
class Books(APIView):
    # 登录后才能操作
    authentication_classes=[Auth,]
    def get(self, request):
        .......
    def post(self, request):
        .......
class BooksDetail(APIView):
    authentication_classes = [Auth, ]
    def get(self, request):
        .......
    def post(self, request):
        .......

# 全局使用
# setting.py
REST_FRAMEWORK = {
    ‘DEFAULT_AUTHENTICATION_CLASSES‘: [‘app01.my_Auth.Auth‘]
}

# 全局使用后局部禁用
# 在所属的试图里写一个空
authentication_classes=[]

2.源码分析

# 第一步
# APIView类
def dispatch(self, request, *args, **kwargs):
    ........
    # 重点是这个,这是认证、频率相关的
    self.initial(request, *args, **kwargs)
    ........
# 第二步
# APIView类
def initial(self, request, *args, **kwargs):
    ........
    # 这个就是认证
    self.perform_authentication(request)

    self.check_permissions(request)
    self.check_throttles(request)
# 第三步
# APIView类
def perform_authentication(self, request):
    # 这个request是已经封装好后的Request的对象
    request.user
# 第四步
# Request类
@property
def user(self):
    if not hasattr(self, ‘_user‘):
        with wrap_attributeerrors():
            self._authenticate()
    return self._user
# 第五步
# Request类
def _authenticate(self):
    # 从下面回到这里,就可以知道
    # self.authenticators=authentication_classes
    # 拿上面的例子举例
    # self.authenticators=[Auth, ];authenticator就是Auth
    for authenticator in self.authenticators:
        try:

# 注意:authenticator.authenticate(self)中的self,由于是在Request类里,所以这个self就是Request实例化的对象request;
# 所以:authenticator.authenticate(self)=Auth.authenticate(self,request)
            user_auth_tuple = authenticator.authenticate(self)
        except exceptions.APIException:
            self._not_authenticated()
            raise

        if user_auth_tuple is not None:
            self._authenticator = authenticator
            # user_auth_tuple:authenticator.authenticate(self)的返回值,是个元组
            # 这就是一个元组的解压
            # self.user:request.user
            # self.auth:request.auth
            self.user, self.auth = user_auth_tuple
            return

   self._not_authenticated()

# self.authenticators的来历
# APIView类
# self.authenticators 是Request实例化的时候传进来的参数self.get_authenticators()
def initialize_request(self, request, *args, **kwargs):
    parser_context = self.get_parser_context(request)

    return Request(
        request,
        parsers=self.get_parsers(),
        authenticators=self.get_authenticators(),
        negotiator=self.get_content_negotiator(),
        parser_context=parser_context
    )

# self.get_authenticators()的来历
# APIView类
def get_authenticators(self):
    # self.authentication_classes
    # 从子类找验证类:authentication_classes = [Auth, ]
    # 从父类APIView里找验证类:authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    # 找到之后,循环并加上()执行
    return [auth() for auth in self.authentication_classes]
    

3.不依靠数据库的token验证

import hashlib
# 设置token
def set_token(id, salt=‘1‘):
    md5 = hashlib.md5()
    md5.update(str(id).encode(‘utf-8‘))
    md5.update(salt.encode(‘utf-8‘))
    return md5.hexdigest() + ‘|‘ + str(id)

# 校验token
def check_token(token, salt=‘1‘):
    tk = token.split(‘|‘)
    md5 = hashlib.md5()
    md5.update(str(tk[-1]).encode(‘utf-8‘))
    md5.update(salt.encode(‘utf-8‘))
    if tk[0] == md5.hexdigest():
        return True
    else:
        return False
class Auth(BaseAuthentication):
    def authenticate(self, request):
        token = request.GET.get(‘token‘)
        # 如果GET里没有token,check_token里的split方法就会报错
        # 所以这里try一下异常
        try:
            ret = common.check_token(token)
            if ret:
                return
            else:
                # 抛异常
                raise
        except Exception as e:
            raise AuthenticationFailed(‘认证失败‘)
class Login(APIView):
    def post(self, request):
        response = {‘status‘: 100, ‘msg‘: ‘登陆成功‘, ‘token‘: None}
        name = request.data.get(‘name‘)
        pwd = request.data.get(‘pwd‘)
        user = models.User.objects.filter(name=name, pwd=pwd).first()
        if user:
            # 传入用户id获得对应的token
            token = common.set_token(user.pk)
            response[‘token‘] = token
        else:
            response[‘status‘] = 200
            response[‘msg‘] = ‘登录失败‘
        return JsonResponse(response, safe=False)

class Book(APIView):
    authentication_classes = [myAuthentication.Auth, ]
    def get(self, request):
        response = {‘status‘: 100, ‘msg‘: ‘查看成功‘, ‘data‘: None}
        books = models.Book.objects.all()
        ret = mySerializers.BookSerializers(books,many=True)
        response[‘data‘]=ret.data
        return JsonResponse(response,safe=False)

4.顺序

认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类

二、权限组件

1.简单使用

from rest_framework.permissions import BasePermission

class VipPermission(BasePermission):
    message = ‘不是会员,查看不了‘

    def has_permission(self, request, view):
        user_type = request.user.user_type
        if user_type == ‘1‘:
            return True
        else:
            return False
class Book(APIView):
    # 局部使用
    permission_classes = [myPermission.VipPermission, ]

    def get(self, request):
        response = {‘status‘: 100, ‘msg‘: ‘查看成功‘, ‘data‘: None}
        books = models.Book.objects.all()
        ret = mySerializers.BookSerializers(books, many=True)
        response[‘data‘] = ret.data
        return JsonResponse(response, safe=False)

# 全局使用
REST_FRAMEWORK = {
    ‘DEFAULT_PERMISSION_CLASSES‘:[‘app01.myPermission.VipPermission‘]
}

# 全局使用中局部禁用
class Book(APIView):
    permission_classes = []

2.源码分析

# 第一步
# APIView类
def dispatch(self, request, *args, **kwargs):
    ........
    # 重点是这个,这是认证、频率以及权限相关的
    self.initial(request, *args, **kwargs)
    ........
# 第二步
# APIView类
def initial(self, request, *args, **kwargs):
    ........
    self.perform_authentication(request)
    # 这就是 权限方法
    self.check_permissions(request)
    self.check_throttles(request)
# 第三步
# APIView类
def check_permissions(self, request):
    # 这里的原理与认证类一致
    for permission in self.get_permissions():
        # 有一点不同的是has_permission(request, self)中的self是APIView的self
        if not permission.has_permission(request, self):
            self.permission_denied(request, message=getattr(permission, ‘message‘, None)
            )

# self.get_permissions()的来历
def get_permissions(self):
   return [permission() for permission in self.permission_classes]

3.顺序

权限类使用顺序:先用视图类中的权限类,再用settings里配置的权限类,最后用默认的权限类

原文地址:https://www.cnblogs.com/xvchengqi/p/10116019.html

时间: 2024-08-30 17:31:30

DAY99 - Rest Framework(四)- 认证组件和权限组件的相关文章

DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分页组件 七 xxx 八 xxx 一 认证组件 1. 局部认证组件 我们知道,我们不管路由怎么写的,对应的视图类怎么写的,都会走到dispatch方法,进行分发, 在咱们看的APIView类中的dispatch方法的源码中,有个self.initial(request, *args, **kwargs),那么认证.权限.频率这三个默认组件都在这个方法里面了,如果我们自己没有做这三个组件的配置,那么会使用源码中默

认证组件、权限组件、频率组件

认证组件.权限组件.频率组件 一.Django权限六张表 1.1.content_type表 """ Course: name.type.days.price.vip_type 基础 免费课 7 0 中级 学位课 180 69 究极 会员课 360 至尊会员 Course: name.type.days.content_type_id 基础 免费课 7 null 中级 学位课 180 1 究极 会员课 360 2 app01_course_1 id.price app01_c

django的RBAC认证z;自定义auth_user表;认证组件权限组件源码分析;认证组件;权限组件

一 RBAC 1.RBAC:全称(Role-Based Access Control):指的是基于用户权限访问控制的认证. 2.Django框架采用的是RBAC认证规则,RBAC认证规则通常会分为:三表规则,五表规则:Django采用的是六表规则. # 三表:用户表.角色表.权限表# 五表:用户表.角色表.权限表.用户角色关系表.角色权限关系表# 六表:用户表.角色表.权限表.用户角色关系表.角色权限关系表.用户权限关系表 3.在Django中六表之间是都是多对多的关系,可通过下面字段跨表访问

drf认证组件、权限组件、jwt认证、签发、jwt框架使用

目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书资源接口 urls.py views.py serializers.py 五.认证组件 重点 自定义认证类 六.权限组件 重点 自定义权限类 七.jwt认证示意图 八. jwt认证算法:签发与校验 签发:根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token 校验:根据客户端带toke

RESTful-rest_framework认证组件、权限组件、频率组件-第五篇

认证组件格式: 1 写一个认证类 from rest_framework.authentication import BaseAuthentication class MyAuth(BaseAuthentication): def authenticate(self,request): # request 是封装后的 token = request.query_params.get('token') ret = models.UserToken.objects.filter(token=toke

三大认证之认证组件和权限组件

一. 源码分析 1. APIView的dispath(self, request, *args, **kwargs) 2. dispath方法内self.initial(request, *args, **kwargs) # 认证组件: 校验用户 - 游客, 合法用户, 非法用户 # 游客: 代表着校验已经通过,直接进入下一步校验(权限校验) # 合法用户: 代表校验通过,将数据保存在request.user中,在进行下一步校验(权限校验) # 非法用户: 代表校验失败,抛出异常,返回403权限

Django Rest Framework 认证组件(权限组件)

from rest_framework.viewsets import ModelViewSet from .authentication_classes import UserAuth from .permission_classes import UserPerm class BookView(ModelViewSet): # 在需要认证的数据接口里面指定认证类 authentication_classes = [UserAuth] # 在需要认证的数据接口里面指定权限类 permissio

Django REST framework —— 权限组件源码分析

在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 1 class ShoppingCarView(ViewSetMixin, APIView): 2 permission_classes = [MyPermission, ] 3 def list(self,request, *args, **kwargs): 4 """ 5 查看购物车信息 6 :param args: 7 :param k

DjangoRestFramework之认证组件,权限组件,频率组件

一 . 认证组件 我们现在知道的认证机制有cookie, session,session比较安全,session的信息是存在服务器上的,如果用户量足够大的话,服务器的压力也就比较大,并且django的session存到了django_session表中,不是很好操作,现在生产中使用的一个叫做token机制的方式比较多.可以使用这个机制把token存到用户信息里,当用户登录成功的时候放里面,等他来的时候就要带着这个来,而且们每次来的时候都更新token,防止被拦截. 我们这里使用一下token,首