rest-framework之认证组件
认证组件
认证简介
作用:校验是否登录
- 首先定义一个类,集成BaseAuthentication,写一个方法:authenticate,在方法内部,实证过程,认证通过,返回None或者两个对象(user,auth),这两个对象,在视图类的request中可以取出来.如果返回的是None,就走下一个认证组件 [xx,xxx]
from rest_framework.authentication import BaseAuthentication
	class myAuthen(BaseAuthentication):
    	def authenticate(self, request):
        	token = request.query_params.get('token')
            ret = models.UserToken.objects.filter(token=token).first()
            if ret:
					# return ret.user, ret
					# 要写多个认证类,这个地返回None
					# 最后一个认证类,返回这俩值
                  return ret.user, ret
              else:
				  raise AuthenticationFailed('您没有登陆')
- 局部使用:只需要在视图类中加入(可以写多个)
authentication_classes = [myAuthen, ]
- 全局使用 setting中设置
REST_FRAMEWORK={
 "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
认证顺序
认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类
局部使用例子
- models 层
class User(models.Model):
    username=models.CharField(max_length=32)
    password=models.CharField(max_length=32)
    user_type=models.IntegerField(choices=((1,'超级用户'),(2,'普通用户'),(3,'二笔用户')))
class UserToken(models.Model):
    user=models.OneToOneField(to='User')
    token=models.CharField(max_length=64)
- 新建认证类(验证通过return两个参数)
from rest_framework.authentication import BaseAuthentication
class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if token_obj:
            return
        else:
            raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
        pass
- view层 登录创建token,并存入数据库,下次登录认证token.
(1) 登录.....
def get_token(username):
    import hashlib
    import time
    md = hashlib.md5()
    # update内必须传bytes格式
    md.update(username.encode('utf-8'))
    md.update(str(time.time()).encode('utf-8'))
    return md.hexdigest()
#认证
class Login(APIView):
    authentication_classes =  [ ]
    def post(self, request):
        response = MyResponse()
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        user = models.User.objects.filter(username=name, password=pwd).first()
        if user:
            response.msg = '登陆成功'
            # 登陆成功,返回一个随机字符串,以后在发请求,都携带这个字符串
            token = get_token(name)
            response.token = token
            #     把随机字符串保存到数据库,有就更新,没有就创建
            #     ret=models.UserToken.objects.update_or_create(user_id=user.id,kwargs={'token':token})
            ret = models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
        else:
            response.msg = '用户名或密码错误'
            response.status = 101
        return JsonResponse(response.get_dic,safe=False)
(2) 登录后 携带token 认证查询数据....
from app01.myauth import myAuthen
class Stus(APIView):
    authentication_classes = [myAuthen,]
    def get(self,request):
        response = MyResponse()
        #认证成功之后,可以去到用户名称,及token
        print(request.user.username)
        print(request.auth.token)
        stus = models.Student.objects.all()
        ret = myserial.StrSer(instance=stus,many=True)
        response.msg = '查询成功'
        response.data = ret.data
        return JsonResponse(response.get_dic,safe=False)
- auth.py
from rest_framework.authentication import BaseAuthentication
#抛出异常,捕捉
from rest_framework.exceptions import AuthenticationFailed
from app01 import models
class myAuthen(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get('token')
        ret = models.UserToken.objects.filter(token=token).first()
        if ret:
            # return ret.user, ret
            # 要写多个认证类,这个地返回None
            # 最后一个认证类,返回这俩值
            return ret.user, ret
        else:
            raise AuthenticationFailed('您没有登陆')
附:不存数据库的token验证 就是通过某种的加密校验规则来验证
def get_token(id,salt='123'):
    import hashlib
    md=hashlib.md5()
    md.update(bytes(str(id),encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    return md.hexdigest()+'|'+str(id)
def check_token(token,salt='123'):
    ll=token.split('|')
    import hashlib
    md=hashlib.md5()
    md.update(bytes(ll[-1],encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    if ll[0]==md.hexdigest():
        return True
    else:
        return False
class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        success=check_token(token)
        if success:
            return
        else:
            raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
        pass
class Login(APIView):
    def post(self,reuquest):
        back_msg={'status':1001,'msg':None}
        try:
            name=reuquest.data.get('name')
            pwd=reuquest.data.get('pwd')
            user=models.User.objects.filter(username=name,password=pwd).first()
            if user:
                token=get_token(user.pk)
                # models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
                back_msg['status']='1000'
                back_msg['msg']='登录成功'
                back_msg['token']=token
            else:
                back_msg['msg'] = '用户名或密码错误'
        except Exception as e:
            back_msg['msg']=str(e)
        return Response(back_msg)
from rest_framework.authentication import BaseAuthentication
class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if token_obj:
            return
        else:
            raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
        pass
class Course(APIView):
    authentication_classes = [TokenAuth, ]
    def get(self, request):
        return HttpResponse('get')
    def post(self, request):
        return HttpResponse('post')
全局使用 在setting中添加
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
源码分析
#Request对象的user方法
@property
def user(self):
the authentication classes provided to the request.
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user
def _authenticate(self):
        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.authenticators
def get_authenticators(self):
	return [auth() for auth in self.authentication_classes]
rest-framework之认证组件的更多相关文章
- restful framework之认证组件
		一.认证介绍 只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 二.局部使用 (1)models层: class Us ... 
- DRF Django REST framework 之 认证组件(五)
		引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ... 
- Django REST Framework之认证组件
		什么是认证 认证即需要知道是谁在访问服务器,需要有一个合法身份.认证的方式可以有很多种,例如session+cookie.token等,这里以token为例.如果请求中没有token,我们认为这是未登 ... 
- 基于django rest framework做认证组件
		先导入要用到的类 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions ... 
- rest framework认证组件和django自带csrf组件区别详解
		使用 Django 中的 csrf 处理 Django中有一个django.middleware.csrf.CsrfViewMiddleware中间件提供了全局的csrf检查.它的原理是在<fo ... 
- Django高级篇三。restful的解析器,认证组件,权限组件
		一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ... 
- 基于Django的Rest Framework框架的认证组件
		0|1一.认证组件的作用 在一个程序中有一些功能是需要登录才能使用的,原生Django中的auth组件可以用来解决这个认证问题,drf框架中也有对应的认证组件来解决这个问题. models.py ... 
- django rest framework 认证组件
		1.认证组件 1.认证组件 1.认证组件 1.认证组件 
- Django REST framework  —— 认证组件源码分析
		我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ... 
- Django-rest framework框架的三大认证组件
		源码分析:三大认证组件的封装 组件的认证配置: 模型层:models.py class User(BaseModel): username = models.CharField(verbose_nam ... 
随机推荐
- 主要的Ajax框架都有什么?
			* Dojo(dojotoolkit.org):* Prototype和Scriptaculous (www.prototypejs.org和script.aculo.us):* Direct We ... 
- mysql从的配置文件
			mysql 从的配置文件 [client]port = 3306socket = /data/mysql/data/mysql.sock#default-character-set=utf8[mysq ... 
- 关于微信小程序切换获取不到元素的问题
			1.由于公司要实现微信小程序的自动化,所以开始学习python + appium 实现微信小程序自动化.在学习过程中遇到在切换webview后获取不到页面元素的问题,导致无法继续.今天在网上看到一篇关 ... 
- fiddler不能抓某些的包的原因
			用fiddler抓某app的包时,死活抓不到,确定自己设置的没有错,并且让小A同事也看了一遍我的设置,确认没错后,又在小A同事那儿试了下还是抓不到 后来在网上找了很多资料,才发现是因为一些app使用了 ... 
- py3.0第四天 函数
			列表生成 # -*- coding: utf-8 -*- # data =[1,2,3] # for index,i in enumerate(data): # print (index,i) # d ... 
- 别人的Linux私房菜(15)磁盘配额与高级文件系统管理
			磁盘配额在网站.邮件.文件等服务器常见,主要有针对用户.用户组.限制某一目录的的最大磁盘配额. ext文件系统进能针对整个文件系统配额,xfs可以针对目录配额.配额和文件系统有关. 内核必须支持磁盘配 ... 
- 渗透测试的理论部分3——ISSAF的详细描述
			ISSAF即信息系统安全评估框架(Information Systems Security Assessment Framework)是另外一种开放源代码的安全性测试和安全分析框架.为了解决安全评估工 ... 
- mysql正则表达式无法识别\d
			无法识别\d 修改为[0-9]就ok 
- GitHub和Git(待补充)
			仓库(Repository):存放项目代码,每个项目对应一个仓库. 收藏(Star) 复制(Fork):克隆并生成新的仓库,from某某.以此为基础修改或应用项目.pull request,源仓库会查 ... 
- 如何定制 antd 的样式(theme)
			> antd 的组件样式(主题)是支持定制的,它的样式实现是基于 less.官方的订制手册参看 https://github.com/ant-design/ant-design/blob/mas ... 
