rest_framework -- 认证组件
2018-12-19 01:46:26来源:博客园 阅读 ()
#####认证组件##### 一、认证是什么就不说了,某些网页必须是用户登陆之后,才能访问的,所以这时候就需要用上认证组件。 你不用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
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- faster-rcnn错误信息 : tensorflow.python.framework.error 2019-07-24
- RobotFramework + HTTP接口自动化实现 2019-07-24
- Django框架之DRF 认证组件源码分析、权限组件源码分析、频率 2019-07-24
- 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源 2019-07-24
- REST Framework 处理一个超链接序列化问题 2019-05-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash