rest-framework:认证组件
一 认证简介:
只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件
二 局部使用
models.py
class User(models.Model):
name=models.CharField(max_length=32)
pwd=models.CharField(max_length=64)
user_type=models.IntegerField(choices=((1,"超级管理员"),(2,"普通管理员"),(3,"2b用户")),default=3)
#跟User表做一对一关联
class Token(models.Model):
user=models.OneToOneField(to='User')
token = models.CharField(max_length=64)
新建认证类(验证通过return两个参数)
rom rest_framework.authentication import BaseAuthentication
from app01 import models
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.permissions import BasePermission
class MyAuth(BaseAuthentication):
def authenticate(self,request):
#写一些认证的逻辑
# print('我是认证类中的方法,只要配置了,一定会走我')
token=request.GET.get('token')
token_obj=models.Token.objects.filter(token=token).first()
if token_obj:
#有值表示登录了
#token_obj.user 当前登录的user对象
return token_obj.user,token_obj
else:
#没有值,表示没有登录,抛异常
raise AuthenticationFailed('您没有登录')
class MyPermision(BasePermission):
message = '不是超级用户,查看不了'
def has_permission(self,request,view):
if request.user.user_type==1:
return True
else:
return False
view层:
from django.shortcuts import render,HttpResponse # Create your views here. from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from django.core.exceptions import ObjectDoesNotExist
from app01 import models
from rest_framework.exceptions import AuthenticationFailed
import uuid
from rest_framework.authentication import BaseAuthentication from app01.MyAuths import MyAuth,MyPermision #用户必须登录之后才能访问获取所有图书接口
class Books(APIView):
#可以写多个认证类
# authentication_classes=[MyAuth,]
#只有超级用户才能访问该接口
permission_classes=[MyPermision,]
def get(self,request):
#request.user 就是当前登录用户
print(request.user.name)
return Response('返回了所有图书') class Publish(APIView):
# authentication_classes = [MyAuth, ]
permission_classes=[]
def get(self,request):
print(request.user.name)
return Response('返回了所有出版社信息')
class Login(APIView):
authentication_classes = []
def post(self,request):
response={'code':100,'msg':'登录成功'}
name=request.data.get('name')
pwd=request.data.get('pwd')
try:
#get 有且只有一条才不报错,其他都抛异常
user=models.User.objects.filter(name=name,pwd=pwd).get()
#登录成功,需要去token表中存数据
#生成一个唯一的idhg
token=uuid.uuid4()
models.Token.objects.update_or_create(user=user,defaults={'token':token})
response['token']=token
except ObjectDoesNotExist as e:
response['code']=101
response['msg']='用户名或密码错误'
except Exception as e:
response['code'] = 102
# response['msg'] = '未知错误'
response['msg'] = str(e)
return Response(response)
附:不存数据库的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')
总结:局部使用,只需要在视图类里加入:
authentication_classes = [TokenAuth, ]
三 全局使用:
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]
认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类
rest-framework:认证组件的更多相关文章
- rest framework认证组件和django自带csrf组件区别详解
使用 Django 中的 csrf 处理 Django中有一个django.middleware.csrf.CsrfViewMiddleware中间件提供了全局的csrf检查.它的原理是在<fo ...
- django rest framework 认证组件
1.认证组件 1.认证组件 1.认证组件 1.认证组件
- Django REST framework —— 认证组件源码分析
我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ...
- restful framework之认证组件
一.认证介绍 只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 二.局部使用 (1)models层: class Us ...
- DRF Django REST framework 之 认证组件(五)
引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ...
- 基于Django的Rest Framework框架的认证组件
0|1一.认证组件的作用 在一个程序中有一些功能是需要登录才能使用的,原生Django中的auth组件可以用来解决这个认证问题,drf框架中也有对应的认证组件来解决这个问题. models.py ...
- Django-rest framework框架的三大认证组件
源码分析:三大认证组件的封装 组件的认证配置: 模型层:models.py class User(BaseModel): username = models.CharField(verbose_nam ...
- rest framework 认证 权限 频率
认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication 源码内部需要 ...
- Django高级篇三。restful的解析器,认证组件,权限组件
一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
随机推荐
- 【Java GC系列】垃圾收集简介(1)
说明: 在本文中, Garbage Collection 翻译为 "垃圾收集", garbage collector 翻译为 "垃圾收集器"; 一般认为, 垃圾 ...
- 重要 | Spark和MapReduce的对比,不仅仅是计算模型?
[前言:笔者将分上下篇文章进行阐述Spark和MapReduce的对比,首篇侧重于"宏观"上的对比,更多的是笔者总结的针对"相对于MapReduce我们为什么选择Spar ...
- POJ2432 Around the world
题意描述 Around the world 在一个圆上有 \(n\) 点,其中有 \(m\) 条双向边连接它们,每条双向边连接两点总是沿着圆的最小弧连接. 求从 \(1\) 号点出发并回到 \(1\) ...
- 修改redo log 的大小
alert日志中含有大量警告信息:"Thread 1 cannot allocate new log, sequence 320xx Checkpoint not complete" ...
- 「SCOI2012」喵星球上的点名
「SCOI2012」喵星球上的点名 先咕着,扔个code跑路 code #include<bits/stdc++.h> #define vec vector #define iter it ...
- c#提取
string email = Console.ReadLine(); int atIndex = email.IndexOf('@'); string userName = email.Substri ...
- leetcode138container-with-water
题目描述 给定n个非负整数a1,a2,-,an,其中每个数字表示坐标(i, ai)处的一个点.以(i,ai)和(i,0)(i=1,2,3...n)为端点画出n条直线.你可以从中选择两条线与x轴一起构成 ...
- Git项目管理出现 .gitignore文件不起作用的解决
在git管理项目的代码过程中总会有需要忽略的目录或者文件,比如编译过程中产生的目录和文件,这时候就需要 .gitignore来进行目录或文件的忽略了. 如果没有 .gitignore文件,可以自己手工 ...
- 客户的一个紧急bug,我用了两种方式进行 C# 反编译修改源码
一:背景 1. 讲故事 周五下午运营反馈了一个紧急bug,说客户那边一个信息列表打不开,急需解决,附带的日志文件也发过来了,看了下日志大概是这样的: 日期:2020-11-13 12:25:45,92 ...
- 自定义圆角背景的textview,抛弃shape
自定义一个圆角背景的TextView,解放双手,不用再写shape了. 1.values目录新建attrs.xml. <?xml version="1.0" encoding ...