#####认证组件#####

一、认证是什么就不说了,某些网页必须是用户登陆之后,才能访问的,所以这时候就需要用上认证组件。
你不用rest_framework的认证组件也行,这种认证的话,完全可以自己写出来。 二、之前再写APIView的时候,那里提到过。
不记得在哪里的话,先找dispatch方法(APIView的记得),然后是self.initial(request, *args, **kwargs),
最后找到self.perform_authentication(request)。看看这个方法的源码: def perform_authentication(self, request):
"""
Perform authentication on the incoming request. Note that if you override this and simply 'pass', then authentication
will instead be performed lazily, the first time either
`request.user` or `request.auth` is accessed.
"""
request.user
## 回忆之前,此时的request是rest_framework进行封装后的request了,所以找到的话,就去rest_framework中Request去找。
## 下面附上request.user这个方法的源码: @property
def user(self):
"""
Returns the user associated with the current request, as authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user
## 它通过property将一个方法装饰成一个属性,此时self是request对象(rest_framework的),经过if判断,执行了self._authenticate()
## 那我们继续去看这个方法是什么,附上源码: def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
for authenticator in self.authenticators:
try:
user_auth_tuple = authenticator.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 self._not_authenticated()
### 此时的self也还是request对象(rest_framework的),self.authenticators这个是什么?
# authenticators它是request的一个属性,那么我们在哪里生成了这个request对象呢?我们回到APIView的dispatch方法,找到这行代码
# request = self.initialize_request(request, *args, **kwargs),有没有印象,得到一个rest_framework的request对象,
# 下面是self.initialize_request(request, *args, **kwargs)的源码: def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
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
)
authenticators=self.get_authenticators() ---->> authenticators是一个装着对象的列表
那么继续看self.get_authenticators()这个方法到底做了些什么,附上源码: def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes]
返回的是一个列表,那么self.authentication_classes应该就是列表(元组),此时self是视图类的对象 ####重点:面向对象属性的查找顺序,记住!!
方式一:我们可以在当前视图类中写一个authentication_classes的列表(元组),里面装着一个一个的类,
而这个类不是随便的一个类,是进行认证验证的类。
方式二:当前视图类中没有authentication_classes这个属性,那么便会去APIView中去找该属性,肯定能APIView中能够找到该属性
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES -->> api_settings它是一个对象
我们去看产生api_settings对象的类,其他的不说了,说说这段代码: @property
def user_settings(self):
if not hasattr(self, '_user_settings'):
self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
return self._user_settings
这里的setting是通过from django.core import settings 导入的
大概意思是:如果django的settings文件中有'REST_FRAMEWORK',那么便会去那里找DEFAULT_AUTHENTICATION_CLASSES这个属性,
没有的话,便会去rest_framework的settings文件中找DEFAULT_AUTHENTICATION_CLASSES,
所以方式二可以这样写,在django的settings文件中写上这样的代码
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[进行认证的类1,进行认证的类2], }
方式三:什么都不写,用rest_framework的settings文件中的DEFAULT_AUTHENTICATION_CLASSES 好了,我们再回到self._authenticate()的源码来看,for循环一个装着对象的列表,所以authenticator就是一个对象,
user_auth_tuple = authenticator.authenticate(self) --->>> 执行该对象的方法,将返回值赋给user_auth_tuple,
我们使用前面的方式一,方式二,自己写认证类的的话,那么必须要有authenticate这个方法对吧,这个先放着,
我们先看方式三,我猜rest_framework的settings文件中的DEFAULT_AUTHENTICATION_CLASSES里的认证类中,也肯定有authenticate方法,
看看它是怎么写,我们跟着写不就好了嘛?
地址:from rest_framework import authentication
看了下每个类中都有authenticate,传来两个参数,一个self,一个request,那我们自己写的认证类也这样写。该方法的返回值将会赋值给user_auth_tuple,
继续回到def _authenticate(self)这个方法中,继续看,如果返回值user_auth_tuple为None的话,将会继续for循环,返回值为True的话,
那么这个返回值必须为一个元组,而且只能有两个元素。执行for循环的过程中,authenticate这个方法没有异常的话,那么表示验证成功。 总结:上面把认证的整个流程都写了一般,那么需要些的东西我列出来,
1、根据需求要求自己写一个认证类,该类必须要有authenticate这个方法,继承BaseAuthentication这个类
2、验证通过的话,返回None或者两个元素的元组(列表也行)
3、验证不通过的话,抛异常,抛这个异常exceptions.APIException
4、假如只想当前视图类中使用认证功能的话,那么在当前视图类中添加authentication_classes属性
5、想全局都想进行认证功能,就在django的settings文件中添加
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[进行认证的类1,进行认证的类2],
}
6、如果你既想全局配置,但是某个局部又不配置认证的话,那么就是该视图类中写authentication_classes,值为[],就好了。 下面写个登陆验证的例子把:test页面必须登陆之后才能访问 models文件:
class User(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
password = models.CharField(max_length=32) class Token(models.Model):
nid = models.AutoField(primary_key=True)
token = models.UUIDField(max_length=64)
user = models.OneToOneField(to='User') urls文件:
url(r'login/',views.Login.as_view()),
url(r'test/',views.Test.as_view()), views文件:
class Login(APIView):
def post(self, request, *args, **kwargs):
response = {'status': 100, 'msg': '登陆成功'}
name = request.data.get('name')
password = request.data.get('password')
try:
user = models.User.objects.get(name=name, password=password)
token = uuid.uuid4()
ret = models.Token.objects.filter(user=user)
if ret:
models.Token.objects.filter(user=user).update(token=token)
else:
models.Token.objects.create(token=token, user=user)
response['token'] = token
except Exception:
response['status'] = 101
response['msg'] = '用户名或密码错误'
return JsonResponse(response) class Test(APIView):
authentication_classes = [LoginAuth,]
def get(self, request, *args, **kwargs):
return HttpResponse('test get') auth_class.py文件: class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token', None)
try:
ret = models.Token.objects.get(token=token)
except ObjectDoesNotExist:
raise exceptions.APIException('请先进行登陆')
return ret.user, ret 这里推荐一个发送各种请求的软件,postman

rest_framework -- 认证组件的更多相关文章

  1. Django的rest_framework认证组件之全局设置源码解析

    前言: 在我的上一篇博客我介绍了一下单独为某条url设置认证,但是如果我们想对所有的url设置认证,该怎么做呢?我们这篇博客就是给大家介绍一下在Rest_framework中如何实现全局的设置认证组件 ...

  2. Django的rest_framework认证组件之局部设置源码解析

    前言: Django的rest_framework组件的功能很强大,今天来我来给大家剖析一下认证组件 下面进入正文分析,我们从视图开始,一步一步来剖析认证组件 1.进入urls文件 url(r'^lo ...

  3. Django之REST_FRAMEWORK 认证组件

    Django之DRF之认证组件 # from rest_framework.views import APIView # APIView 中的 dispatch 中 执行的 self.initial( ...

  4. rest_framework 认证组件 权限组件

    认证组件 权限组件 一.准备内容 # models class User(models.Model): name = models.CharField(max_length=32) pwd = mod ...

  5. 002---rest_framework认证组件

    rest_framework认证组件 问题:有些API,需要用户登录才能访问,有些无需登录就能访问. 解决: a. 创建两个模型类:UserInfo---OneToOne---UsetToken b. ...

  6. DRF认证组件

    1.DRF认证组件之视图注册用法(自定义简单使用) settings.py配置 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.a ...

  7. Django-restframework 源码之认证组件源码分析

    Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...

  8. drf视图组件、认证组件

    视图组件 1.基本视图 url(r'^publish/$', views.PublishView.as_view()), url(r'^publish/(?P<pk>\d+)/$', vi ...

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

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

随机推荐

  1. Android开发ListView嵌套ImageView实现单选按钮

    做Android开发两年的时间,技术稍稍有一些提升,刚好把自己实现的功能写出来,记录一下,如果能帮助到同行的其他人,我也算是做了件好事,哈哈!!废话不多说,先上个图. 先上一段代码: if (last ...

  2. Ubuntu真机安装

    Ubuntu真机安装 1.Ubuntu安装: (1)启动盘制作: a.下载启动盘制作工具Universal USB Installe,下载地址: b.下载Ubuntu系统镜像,到本地磁盘,官方下载地址 ...

  3. AE多用户同时编辑同一个版本数据的解决方法

    项目中做了入库的功能,测试一切正常,但是实际使用多个用户同时编辑default版本的时候,问题就来了,StopEditing 错误信息如下 FDO_E_VERSION_REDEFINED -21472 ...

  4. 使用CKRule实现促销管理系统

    1, 常见的促销模型 促销管理系统在很多地方都有使用,大家去超市就经常体现到,感受到,不少中小型单位都其促销活动,要搞促销活动最好是有应用软件支持,这样就比较灵活管理也方便.而依靠手工处理的话效率会比 ...

  5. android学习之VelocityTracker

    今天大概的学习了一下 VelocityTracker ,用来监控手势速度的,在View移动过程中,可以有个缓冲的移动.  我觉得初步的使用起来是很简单的. 首先移动依靠的是Scroller类,Scro ...

  6. php json_encode 中文乱码解决方法

    本文列举3个方法,实现json_encode()后的string显示中文问题. 做接口时不需要,但存log时帮了大忙了. 在贴代码前,必须贴上官方param和return,链接:http://php. ...

  7. Excel VBA 复制

    将 Sheet1 复制到 Sheet3 后面时,实现方法如下: Worksheets("Sheet1").Copy After:=Worksheets("Sheet3&q ...

  8. Orchard Core 文档翻译 (六)HTML

    Body (OrchardCore.Html) Theming Shapes 将HtmlBodyPart附加到内容类型时,将呈现以下形状(Shapes) Name Display Type Defau ...

  9. 我的HTML总结之表单

    表单是Web中实现交互的重要方法,用于收集用户信息并提交给服务器.   表单中的9大控件 <input type="text" name="key" va ...

  10. 如何查找Fiori UI上某个字段对应的后台存储表的名称

    今天微信群里有朋友问到这个问题. 如果是SAPGUI里的事务码,比如MM01,对于开发者来说这个任务非常容易完成. 比如我想知道下图"Sales Unit"这个字段的值到底保存在哪 ...