span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-searching {background: #ffa; background: rgba(255, 255, 0, .4);}.cm-force-border { padding-right: .1px; }@media print { .CodeMirror div.CodeMirror-cursors {visibility: hidden;}}.cm-tab-wrap-hack:after { content: ""; }span.CodeMirror-selectedtext { background: none; }.CodeMirror-activeline-background, .CodeMirror-selected {transition: visibility 0ms 100ms;}.CodeMirror-blur .CodeMirror-activeline-background, .CodeMirror-blur .CodeMirror-selected {visibility:hidden;}.CodeMirror-blur .CodeMirror-matchingbracket {color:inherit !important;outline:none !important;text-decoration:none !important;}.CodeMirror-sizer {min-height:auto !important;}
-->
li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style-type:lower-latin;}.wiz-editor-body ol.wiz-list-level3 > li {list-style-type:lower-roman;}.wiz-editor-body li.wiz-list-align-style {list-style-position: inside; margin-left: -1em;}.wiz-editor-body blockquote {padding: 0 12px;}.wiz-editor-body blockquote > :first-child {margin-top:0;}.wiz-editor-body blockquote > :last-child {margin-bottom:0;}.wiz-editor-body img {border:0;max-width:100%;height:auto !important;margin:2px 0;}.wiz-editor-body table {border-collapse:collapse;border:1px solid #bbbbbb;}.wiz-editor-body td,.wiz-editor-body th {padding:4px 8px;border-collapse:collapse;border:1px solid #bbbbbb;min-height:28px;word-break:break-word;box-sizing: border-box;}.wiz-editor-body td > div:first-child {margin-top:0;}.wiz-editor-body td > div:last-child {margin-bottom:0;}.wiz-editor-body img.wiz-svg-image {box-shadow:1px 1px 4px #E8E8E8;}.wiz-hide {display:none !important;}
-->

上篇随笔中我们看到在restframework.views的dispatch是请求的处理入口,里面先是通过initialize_request将request进行封装,封装后的request不仅仅有原先的request,还有解析器,认证,以及渲染。
  • 认证
        authenticators=self.get_authenticators()
        看get_authenticators干了什么:        
          明显的列表推导式 self.authentication_classes:
         
           这是APIView的属性,很熟悉吧?因为几乎使用restframework的项目中几乎都会在项目的setting.py文件中配置它,比如:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
)
}<wiz_code_mirror>

 
 
 
7
 
 
 
 
 
1
REST_FRAMEWORK = {
2
    'DEFAULT_AUTHENTICATION_CLASSES': (
3
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
4
        'rest_framework.authentication.SessionAuthentication',
5
        'rest_framework.authentication.BasicAuthentication',
6
    )
7
}
 
 
        容易理解,默认是读取项目setting.py的文件,dispatch中initialize_request将找到的验证器封装到request对象中,接下来
        执行了initial方法

       

      

        self.perform_authentication(request)  负责进行验证:
             
        执行了request.user:
             
       

    

        这里我们看到实际调用了self._authenticate()
        

            解释:
      • for authenticator in self.authenticators:          
                通过遍历找到我们的认证器
      • user_auth_tuple = authenticator.authenticate(self)
                            执行认证器的authenticate(self)方法    所以在认证器中必须实现这个方法   返回值是一个元组
      • except exceptions.APIException:    self._not_authenticated()     raise
                             如果认证类出现异常,就抛出这个异常,认证失败
      • if user_auth_tuple is not None:
                                self._authenticator = authenticator
                                self.user, self.auth = user_auth_tuple
                                return
                              验证通过,将user_auth_tuple的两个元素分别赋值给request的user和auth
      • self._not_authenticated()
                       
                      如果所有的认证器都没抛出异常,且返回值都是None,就执行这个函数,也就也是匿名用户,可在seeting.py中配置    
 
     
        既然我们的CBV是继承于APIView,那自然就可以在函数中定义DEFAULT_AUTHENTICATION_CLASSES,并编写我们自己的认证方式:    
from rest_framework.exceptions import AuthenticationFailed
class MyAuthentication(object):
# authenticate authenticate_header 两个方法是必须有的,authenticate用来写我们自己的认证方式,authenticate_header直接写pass就行,不写会抛错,缺少authenticate_header方法
def authenticate(self, request):
self.token = request._request.GET.get('token')
if not self.token:
raise AuthenticationFailed('用户认证失败') # 如果认证失败,就抛出一个AuthenticationFailed异常
return ('wbj', self.token) # 如果认证通过,就行返回一个元组,第一个元素是用户身份(user),第二个是auth

def authenticate_header(self, request):
pass

 
 
 
11
 
 
 
 
 
1
from rest_framework.exceptions import AuthenticationFailed
2
class MyAuthentication(object):
3
    # authenticate authenticate_header 两个方法是必须有的,authenticate用来写我们自己的认证方式,authenticate_header直接写pass就行,不写会抛错,缺少authenticate_header方法
4
    def authenticate(self, request):
5
        self.token = request._request.GET.get('token')
6
        if not self.token:
7
            raise AuthenticationFailed('用户认证失败')   # 如果认证失败,就抛出一个AuthenticationFailed异常
8
        return ('wbj', self.token)      # 如果认证通过,就行返回一个元组,第一个元素是用户身份(user),第二个是auth
9

10
    def authenticate_header(self, request):      # 如果不想写这个方法,可以让MyAuthentication继承于rest_framework.authentication.BaseAuthentication

11
        pass
 
 
       使用MyAuthentication进行身份认证:
class Book(APIView):
authentication_classes = [MyAuthentication, ]

def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)

def get(self, request):
# get a book
return HttpResponse(json.dumps({'code': '20000'}))

def post(self, request):
return HttpResponse(json.dumps({'code': '20000'}))

def put(self, request):
# update a book
return HttpResponse(json.dumps({'code': '20000'}))

def delete(self, request):
# delete a book
return HttpResponse(json.dumps({'code': '20000'}))

 
 
 
x
 
 
 
 
 
1
class Book(APIView):
2
    authentication_classes = [MyAuthentication, ]
3

4
    def dispatch(self, request, *args, **kwargs):
5
        return super().dispatch(request, *args, **kwargs)
6

7
    def get(self, request):
8
        # get a book
9
        return HttpResponse(json.dumps({'code': '20000'}))
10

11
    def post(self, request):
12
        return HttpResponse(json.dumps({'code': '20000'}))
13

14
    def put(self, request):
15
        # update a book
16
        return HttpResponse(json.dumps({'code': '20000'}))
17

18
    def delete(self, request):
19
        # delete a book
20
        return HttpResponse(json.dumps({'code': '20000'}))
 
 
       
 
   进行测试:
       
 
   带token请求

      
 
        不带token请求
       

      
 
 
 
 
 
 
 
            
        

从FBV到CBV二(认证器)的更多相关文章

  1. django的FBV和CBV的装饰器例子

    备忘 def auth(func): def inner(request,*args,**kwargs): u = request.COOKIES.get('username111') if not ...

  2. 一、虚拟环境.二、路由配置主页与404.三、2.x路由分发.四、伪静态.五、request对象.六、FBV与CBV.七、文件上传.

    一.虚拟环境 ''' 解决版本共存 1. 用pycharm选择File点击NewProject然后选择virtualenv创建一个纯净环境 2. 打开下载的目录将venv文件夹下的所有文件(纯净的环境 ...

  3. django基础 -- 4. 模板语言 过滤器 模板继承 FBV 和CBV 装饰器 组件

    一.语法 两种特殊符号(语法): {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 二.变量 1. 可直接用  {{ 变量名 }} (可调用字符串, 数字 ,列表,字典,对象等) ...

  4. diango中的MTV——FBV/CBV以及装饰器的复用问题解决

    MVC M: model 模型 与数据库交互 V: view 视图 HTML C:controller 控制器 流程 和 业务逻辑 MTV M:model ORM T:template 模板 HTML ...

  5. epic游戏平台如何启用认证器应用程序/二次验证码/谷歌身份验证器?

    1.登陆epic游戏平台,找到二次验证绑定界面 登陆https://www.epicgames.com/store/zh-CN/, 点右上角用户头像-[账户]. 之后点-[密码与安全] 在[双重验证] ...

  6. Django FBV和CBV -

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  7. CBV加装饰器解决登录注册问题和 <<中间件>>

    文本目录 CBV加装饰器解决登录注册问题 一:什么是中间件 二:中间件有什么用 三:自定义中间件 四:中间件应用场景 五:SCRF TOKEN跨站请求伪造 六: 其他操作 CBV加装饰器解决登录注册问 ...

  8. Python菜鸟之路:Django 路由补充1:FBV和CBV - 补充2:url默认参数

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  9. Django CBV加装饰器、Django中间件、auth模块

    一. CBV加装饰器 在视图层中,基于函数的视图叫FBV(function base views),基于类的视图叫CBV(class base views).当需要用到装饰器时,例如之前的基于Cook ...

随机推荐

  1. Angularjs E2E test Report/CoverageReport - 使用Gulp

    上一篇(http://www.cnblogs.com/xiaoningz/p/7122633.html)使用grunt-protractor-coverage 做为覆盖率测试插件,如果项目的管理工具刚 ...

  2. [笔记] 使用v2r访问外网

    介绍 首先,你需要有一台能上外网的服务器,如AWS,GCP等. 其次,请自行复制全文,然后将FXXK替换为v2r的全称(5个小写字符). 服务器上Docker镜像配置流程 拉取镜像 $ sudo do ...

  3. MyEclipse 下'Publishing to Tomcat'has encountered a problem解决办法

    详情查看: MyEclipse 下'Publishing to Tomcat'has encountered a problem解决办法

  4. 直方图匹配原理与python、matlab实现

    直方图匹配本质上是让两幅图像的累积直方图尽量相似,累积直方图相似了,直方图也就相似了. 把原图像img的直方图匹配到参考图像ref的直方图,包括以下几个步骤: 1. 求出原图像img的累积直方图img ...

  5. collections(python常用内建模块)

    文章来源:https://www.liaoxuefeng.com/wiki/897692888725344/973805065315456 collections collections是Python ...

  6. 阿里云Open API自动化脚本—ECS公网IP转化弹性公网IP

    1.OpenAPI Explorer 记录一下使用阿里云 Open API 自动化/脚本化 “ECS 公网 IP 转化弹性公网 IP”的实现 全过程.原博客地址:https://www.markedi ...

  7. 使用 docsify 創建自己的 markdown 文檔系統

    先來看一下我在碼雲上創建的demo: http://lin1270.gitee.io/nicedoc/#/ GIT自己clone一下: https://gitee.com/lin1270/nicedo ...

  8. python list pop()方法

    #pop()用于移除列表中的一个元素(默认是最后一个元素,并且返回该元素的值) list1=['Google','Runoob','Taobao'] list_pop=list1.pop() prin ...

  9. 小记---------spark优化之更优分配资源

      spark优化:在一定范围之内,增加资源与性能的提升是成正比的. 因此,       一个cpu core  执行一个task线程. task数: 若有 cpu core 2个.num-execu ...

  10. 设计模式在 Spring 框架中的良好应用

    在开始正文之前,请你先思考几个问题: 你项目中有使用哪些 GOF 设计模式 说一说 GOF 23 种设计模式的设计理念 说说 Spring 框架中如何实现设计模式 假设我是面试官问起了你这些面试题,你 ...