MOZ中文网
  • 首页
  • Fantaverse中文网
  • 领取MOLI红包
    Fantaverse中文网你的位置:MOZ中文网 > Fantaverse中文网 > Restful framework【第六篇】认证组件
    Restful framework【第六篇】认证组件
    发布日期:2025-01-03 18:37    点击次数:105

    基本用法 简单实例 settings 先创建一个project和一个app(我这里命名为API) 首先要在settings的app中添加 url models 一个保存用户的信息 一个保存用户登录成功后的token views 用户登录(返回token并保存到数据库) 利用postman发请求 如果用户名和密码正确的话  会生成token值,下次该用户再登录时,token的值就会更新  数据库中可以看到token的值 当用户名或密码错误时,抛出异常 添加认证  基于上面的例子,添加一个认证的类 url views 用postman发get请求 请求的时候没有带token,可以看到会显示“用户认证失败”    这样就达到了认证的效果,django-rest-framework的认证是怎么实现的呢,下面基于这个例子来剖析drf的源码。   drf的认证源码分析 源码流程图   请求先到dispatch dispatch()主要做了两件事 封装request 认证   具体看我写的代码里面的注释 reuqest (1)initialize_request() 可以看到initialize()就是封装原始request (2)get_authenticators() 通过列表生成式,返回对象的列表  (3)authentication_classes  APIView里面有个  authentication_classes   字段 可以看到默认是去全局的配置文件找(api_settings) 认证 self.initial(request, *args, **kwargs) (1)initial()  主要看 self.perform_authentication(request),实现认证  (2)perform_authentication()  调用了request.user (3)user request.user的request的位置 点进去可以看到Request有个user方法,加 @property 表示调用user方法的时候不需要加括号“user()”,可以直接调用:request.user (4)_authenticate()  循环所有authenticator对象 返回值就是例子中的: token_obj.user-->>request.user token_obj-->>request.auth 当都没有返回值,就执行self._not_authenticated(),相当于匿名用户,没有通过认证 面向对象知识: 子类继承 父类,调用方法的时候: 优先去自己里面找有没有这个方法,有就执行自己的 只有当自己里面没有这个方法的时候才会去父类找  因为authenticate方法我们自己写,所以当执行authenticate()的时候就是执行我们自己写的认证 父类中的authenticate方法  我们自己写的 认证的流程就是上面写的,弄懂了原理,再写代码就更容易理解为什么了。 配置文件 继续解读源码  默认是去全局配置文件中找,所以我们应该在settings.py中配置好路径 api_settings源码 setting中‘REST_FRAMEWORK’中找 全局配置方法: API文件夹下面新建文件夹utils,再新建auth.py文件,里面写上认证的类 settings.py auth.py 在settings里面设置的全局认证,所有业务都需要经过认证,如果想让某个不需要认证,只需要在其中添加下面的代码: from django.shortcuts import render,HttpResponse from django.http import JsonResponse from rest_framework.views import APIView from API import models from rest_framework.request import Request from rest_framework import exceptions from rest_framework.authentication import BasicAuthentication ORDER_DICT = { 1:{ 'name':'apple', 'price':15 }, 2:{ 'name':'dog', 'price':100 } } def md5(user): import hashlib import time #当前时间,相当于生成一个随机的字符串 ctime = str(time.time()) m = hashlib.md5(bytes(user,encoding='utf-8')) m.update(bytes(ctime,encoding='utf-8')) return m.hexdigest() class AuthView(APIView): '''用于用户登录验证''' authentication_classes = [] #里面为空,代表不需要认证 def post(self,request,*args,**kwargs): ret = {'code':1000,'msg':None} try: user = request._request.POST.get('username') pwd = request._request.POST.get('password') obj = models.UserInfo.objects.filter(username=user,password=pwd).first() if not obj: ret['code'] = 1001 ret['msg'] = '用户名或密码错误' #为用户创建token token = md5(user) #存在就更新,不存在就创建 models.UserToken.objects.update_or_create(user=obj,defaults={'token':token}) ret['token'] = token except Exception as e: ret['code'] = 1002 ret['msg'] = '请求异常' return JsonResponse(ret) class OrderView(APIView): '''订单相关业务''' def get(self,request,*args,**kwargs): # self.dispatch #request.user #request.auth ret = {'code':1000,'msg':None,'data':None} try: ret['data'] = ORDER_DICT except Exception as e: pass return JsonResponse(ret) API/view.py代码  再测试一下我们的代码 不带token发请求     带token发请求   drf的内置认证  rest_framework里面内置了一些认证,我们自己写的认证类都要继承内置认证类 "BaseAuthentication" BaseAuthentication源码: 修改自己写的认证类 自己写的Authentication必须继承内置认证类BaseAuthentication 其它内置认证类 rest_framework里面还内置了其它认证类,我们主要用到的就是BaseAuthentication,剩下的很少用到 总结 只要用了drf,post提交数据,就不需要csrf验证了,源码里对View用了禁用csrf  自己写认证类方法梳理 (1)创建认证类 继承BaseAuthentication    --->>1.重写authenticate方法;2.authenticate_header方法直接写pass就可以(这个方法必须写) (2)authenticate()返回值(三种) None ----->>>当前认证不管,等下一个认证来执行 raise exceptions.AuthenticationFailed('用户认证失败')       # from rest_framework import exceptions  有返回值元祖形式:(元素1,元素2)      #元素1复制给request.user;  元素2复制给request.auth (3)局部使用 authentication_classes = [BaseAuthentication,] (4)全局使用 源码流程 --->>dispatch     --封装request        ---获取定义的认证类(全局/局部),通过列表生成式创建对象       ---initial        ----peform_authentication          -----request.user   (每部循环创建的对象)     

    Powered by MOZ中文网 @2013-2022 RSS地图 HTML地图

    Copyright Powered by站群系统 © 2013-2024