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. 使用 certbot 自动给 nginx 加上 https

    概述 目前,Let's Encrypt 可以算是最好用的 https 证书申请网站了吧.而 certbot 可以算是它的客户端,能够很方便的自动生成 https 证书.我把自己的使用经历记录下来,供以 ...

  2. openstack核心组件--keystone(1)

    一.keystone介绍 keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户权限的定义等等 ...

  3. webrtc实现点对点视频通讯

    html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. git 参考手册-简明指南

    很久没发文了,来头条以后更忙了,也没精力去分享一些有营养的内容了.这次分享的 git 的方方面面,基本来自于我的笔记.git 这东西算是为数不多每天都要用的东西了,但是我觉得也不至于从头至尾去了解他的 ...

  5. 安装 Git 并连接 Github

    下载安装 Git, 下载地址:https://git-scm.com/download/win . 在命令行中输入 git 测试 Git 是否安装成功. 在桌面鼠标右击打开 Git Bash Here ...

  6. Leetcode之动态规划(DP)专题-931. 下降路径最小和(Minimum Falling Path Sum)

    Leetcode之动态规划(DP)专题-931. 下降路径最小和(Minimum Falling Path Sum) 给定一个方形整数数组 A,我们想要得到通过 A 的下降路径的最小和. 下降路径可以 ...

  7. Java 高级 --- 多线程快速入门

    这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 多线程快速入门 1.线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组 ...

  8. webdriervAPI(键盘事件)

    from  selenium  import  webdriver from selenium.webdriver.common.keys import Keys   #导入键盘操作事件 driver ...

  9. 快速分析CPU性能问题

    Linux的CPU性能问题,相信在工作中很容易遇到.这篇文章会总结出一个大概的套路,相信能够解决工作中90%以上的CPU性能问题! 会告诉大家在不同的场景下,cpu性能指标工具如何选择,性能瓶颈怎么找 ...

  10. ng-zorro等组件默认样式的修改

    https://www.jianshu.com/p/8b887c2aac06 在项目中修改ng-zorro组件默认样式的一些方法: 类名等 前加::ng-deep: 类名等 前加:root: 类名等 ...