REST_FRAMEWORK之认证authenticate

REST_FRAMEWORK重要组件--->authentication

1.认证(authenticate)

(1).对于某些API来说是需要做完访问认证才能查看网页内容的,比如说get请求带token认证字段。
(2).对于认证的流程来说,无论是认证、权限、节流、版本、
     解析器还是其他的组件,入口都是self.dispatch()
(3).认证的流程为 请求进来->self.dispatch()>request=self.initialize_request(request,*args,kwargs)
->return Request() 返回一个Request对象,里面包括一个原生的request和self.get_Authenticators()方法get_Authenticators()方法是将一个authentication_Classes列表里面的对象进行实例化。首先找继承BaseAuthentication的视图函数是否有authenticate/authenticate_header这两个函数,如果没有,找父类的。其中authenticate回去挨个遍历authentication_classes列表中的认证,如果认证成功了,才会去执行dispatch中剩下来的getattr()去进行反射,去执行对相应method的操作,认证可以是单个,也可是多个,也可以为空
(4).认证操作继承BaseAuthentication里面有authenticateauthenticate_header 两个函数必须要重写。其中authenticate(self,request)函数里面,获取url参数可以为request._request.Get.get(‘token’),authenticate_header(self,request)函数里面,可以省略,直接pass过。
(5).部分认证和全局认证:所谓的部分认证就是在app下面写了一个自定义的authentication类,比如名字叫MyAuthentication(BaseAuthentication)类
在这里插入图片描述


class MyAuthentication(BaseAuthentication):
   def authenticate(self, request):
       token=request._request.GET.get('token')
       token_obj=models.Usertoken.objects.filter(token=token).first()
       print(token_obj)
       if not token_obj:
           raise exceptions.AuthenticationFailed("用户登录失败")
       return (token_obj.user,token_obj)       #这一步是关键,如果没有返回这两个参数,默认是匿名用户登录的
                                               #这对于权限来说是致命的,因为认证返回None,则权限不能利用request.user.login_type字段
                                               #user是UserInfo表和UserToken表的一对一字段。权限验证就会报错报错:
                                               #'AnonymousUser' object has no attribute 'login_type'
   def authenticate_header(self, request):
       pass


from rest_framework.views import APIView
# Create your views here.
from django.http import JsonResponse
from test3 import models


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 = [MyAuthentication,]
    def post(self,request,*args,**kwargs):
       #self.dispatch()
        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 =md5(user)
            #update_or_create传参时候的user是Usertoken里面的一对一字段
            models.Usertoken.objects.update_or_create(user=obj,defaults={'token':token})
            ret['token']=token

        except Exception as e:
            print(e)

        return JsonResponse(ret)

        AuthView这个类就是一个部分认证的类在每个类去调用这个MyAuthentication的时候都要写上这么一句authentication_classes=[MyAuthentication,]
       何谓全局认证?就是在app下专门写一个authentication类,在settings中设置一个REST_FRAMEWORK{}的字典变量。里面的认证可以是一个,也可以是多个。

"DEFAULT_AUTHENTICATION_CLASSES":['test3.utils.auth.Authenticationfirst',],

做完全局变量最重要的一点是按照不同的认证在视图类下重写authentication_classes列表,比如全局变量中有两个认证token类,那就意味着继承每个视图类都需要进行一个token的认证。如果想让某个类免除认证就需要在免除认证的视图下写上authentication_classes = [,]。
解析上面的例子:上面的例子其实就是做了一个用户利用token认证和username、password登陆的用户登录。虽然token、username、password三者是同时传给后台,但是却是先做的认证,认证通过了,再去检验username、password字段的值是否正确。利用MD5配合time.time()随机生成一个token字符串,再利用ORM的update_or_create(不存在即创建,存在则更新)进行存储

`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值