django-rest-framework 基础三 认证、权限和频率
django-rest-framework 基础三 认证、权限和频率
1. 认证
登录接口: 登录成功只要给前端返回json格式字符串,这个字符串中带一个随机字符串(可以使用uuid生成)
登录接口步骤:
前端传入用户名和密码,然后去user表中查找,能找到说明用户和密码没问题,登录成功,然后在userToken表中存一条记录,说明登录过了,再返回前端一个json字符串
1.1 登录接口
models.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=64)
password = models.CharField(max_length=128)
user_type = models.IntegerField(choices=((1, "超级管理员"),(2,"管理员"),(3,"普通用户")))
class UserToken(models.Model):
user = models.OneToOneField(to=User,on_delete=models.CASCADE)
userToken = models.CharField(max_length=64)
views.py
from django.shortcuts import render
# Create your views here.
from rest_framework.viewsets import GenericViewSet
from authenticated.models import User,UserToken
from rest_framework.response import Response
from rest_framework.decorators import action
import uuid
class UserView(GenericViewSet):
@action(methods=['POST'], detail=False)
def login(self,request):
username = request.data.get("username")
password = request.data.get("password")
user = User.objects.filter(username=username, password=password).first()
if not user:
return Response({"code":1001,"msg":"用户名或密码错误"})
token = str(uuid.uuid4()) # 获取一个不重复的值,做唯一标识
# userToken表中有就更新,没有就创建
#UserToken.objects.update_or_create(user=user, defaults={'token': token})
UserToken.objects.update_or_create(user=user, defaults={'userToken': token})
# 返回信息,并带着token
return Response({"code":1000,"msg":"登录成功",'userToken': token})
urls.py
from django.contrib import admin
from django.urls import path,include
from authenticated import views
from rest_framework import routers
router = routers.SimpleRouter()
router.register('user',views.UserView, "user")
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls))
]
访问:
post请求: http://127.0.0.1:8000/user/login/
1.2 认证
有了登录接口,就可以实现认证,如果要调用别的接口必须要先登录才可以。
例如有个图书的表有五个接口,要访问图书的五个接口必须就登录。
步骤:
1. 先写一个类,继承BaseAuthentication,并重写authenticate方法,在方法中校验是否登录,登录则返回两个值,没有则拋异常
from rest_framework.authentication import BaseAuthentication
class xxxx(BaseAuthentication):
def authenticate(self, request):
2. 全局配置和局部配置
全局配置:
settings.py中
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":["authenticated.authentication.LoingAuth"]
}
局部配置:
在视图类中:
authentication_classes = [xxxx,]
禁止局部署配置:
authentication_classes = []
登录则返回两个值:
request.user 当前登录的用户
request.auth 为当前登录用户的token
示例:
models.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=64)
password = models.CharField(max_length=128)
user_type = models.IntegerField(choices=((1, "超级管理员"),(2,"管理员"),(3,"普通用户")))
class UserToken(models.Model):
user = models.OneToOneField(to=User,on_delete=models.CASCADE)
userToken = models.CharField(max_length=64)
class Book(models.Model):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=5, decimal_places=2)
author = models.CharField(max_length=64)
认证功能,在app中新建authentication.py
from rest_framework.authentication import BaseAuthentication
from authenticated.models import UserToken
from rest_framework.exceptions import AuthenticationFailed
class LoingAuth(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
user_token = UserToken.objects.filter(userToken=token).first()
if not user_token:
raise AuthenticationFailed("请先登录")
return user_token.user, token
views.py
from django.shortcuts import render
# Create your views here.
from rest_framework.viewsets import GenericViewSet
from authenticated.models import User,UserToken
from rest_framework.response import Response
from rest_framework.decorators import action
import uuid
from rest_framework.viewsets import ModelViewSet
from authenticated.models import Book
from authenticated.serializer import BookSerializer
from authenticated.authentication import LoingAuth
class UserView(GenericViewSet):
@action(methods=['POST'], detail=False)
def login(self,request):
username = request.data.get("username")
password = request.data.get("password")
user = User.objects.filter(username=username, password=password).first()
if not user:
return Response({"code":1001,"msg":"用户名或密码错误"})
token = str(uuid.uuid4())
# userToken表中有就更新,没有就创建
#UserToken.objects.update_or_create(user=user, defaults={'token': token})
UserToken.objects.update_or_create(user=user, defaults={'userToken': token})
return Response({"code":1000,"msg":"登录成功",'token': token})
class BookView(ModelViewSet):
# 只对BookView单独进行认证(局部配置)
authentication_classes = [LoingAuth,]
queryset = Book.objects.all()
serializer_class = BookSerializer
路由urls.py
from django.contrib import admin
from django.urls import path,include
from authenticated import views
from rest_framework import routers
router = routers.SimpleRouter()
router.register('user',views.UserView, "user")
router.register('books', views.BookView,"books")
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls))
]
全局配置settings.py
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":["authenticated.authentication.LoingAuth"],
}
# authenticated.authentication.LoingAuth 为写的认证的类
# 全局配置后局部配置的就可以取消了。
# 但是全局配置后如果有些类不想让它有认证,比如登录接口,它不能有认证否则就死循环了。
# 全局配置后,单独取消某一个接口的认证:
class UserView(ViewSet):
authentication_classes = [] # 让它等于空就可以了。
2. 权限
所有的接口必须登录后才能访问(给每个视图加认证),登录成功后如果是普通用户则只可查看全部或单条数据。如果想要增删改必须是管理员或超级管理员。
演示可以把五个接口写成两个视图:
在应用目录下创建permission.py文件
permission.py
from rest_framework.permissions import BasePermission
class userPermission(BasePermission):
def has_permission(self, request, view):
user_type = request.user.user_type
# (1, "超级管理员"),(2,"管理员"),(3,"普通用户"),如果小于3说明是管理或超管用户
if user_type <3:
return True
else:
return False
视图views.py
from rest_framework.viewsets import GenericViewSet
from authenticated.models import User, UserToken
from authenticated.models import Book
from authenticated.serializer import BookSerializer
from authenticated.authentication import LoingAuth
from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin, UpdateModelMixin, \
RetrieveModelMixin
#用户登录接口此处省略(见上面1.2认证)
# 查看全部和单条。只要登录了谁都可以访问
class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin):
authentication_classes = [LoingAuth, ]
queryset = Book.objects.all()
serializer_class = BookSerializer
# 只有管理和超管用户可以 创建、修改、新增
from authenticated.permission import userPermission
class BookDetailView(GenericViewSet, CreateModelMixin, UpdateModelMixin, DestroyModelMixin):
authentication_classes = [LoingAuth]
permission_classes = [userPermission]
queryset = Book.objects.all()
serializer_class = BookSerializer
路由 urls.py:
from django.contrib import admin
from django.urls import path,include
from authenticated import views
from rest_framework import routers
router = routers.SimpleRouter()
router.register('user',views.UserView, "user")
router.register('books', views.BookView,"books")
router.register('bookdetail', views.BookDetailView,"bookdetail")
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls))
]
全局配置settings.py
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":["authenticated.permission.userPermission"],
}
# authenticated.permission.userPermission 为写的权限的类
# 全局配置后局部配置的就可以取消了。
# 全局配置后,单独取消某一个接口的权限:
class UserView(ViewSet):
permission_classes = [] # 让它等于空就可以了。
普通用户访问的时候会报没有权限

2.1 权限总结:
两个视图:
BookView:获取所有,获取单条
BookDetailView:删除,修改,新增
上面两个视图都需要登录:authentication_classes = [LoginAuth, ]
BookDetailView必须有权限才能,加了一个权限,permission_classes = [UserPermission, ]
编写权限步骤
第一步:写一个类,继承BasePermission,重写has_permission,判断如果有权限,返回True,如果没有权限,返回False
第二步:局部配置和全局配置
局部配置
class BookDetailView(GenericViewSet, CreateModelMixin, DestroyModelMixin, UpdateModelMixin):
permission_classes = [UserPermission, ]
全局配置
settings.py
REST_FRAMEWORK={
"DEFAULT_PERMISSION_CLASSES":["authenticated.permission.userPermission",]
}
3. 频率
限制访问的频率
在应用目录创建throttle.py文件用来限制频率
throttle.py
from rest_framework.throttling import SimpleRateThrottle
class IpThrottle(SimpleRateThrottle):
scope = 'min_3' # 在settings.py定义给哪个类限制的频率
# get_cache_key 返回什么就以什么做限制,现在是以IP做限制
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR') # 返回的是客户端的IP,以IP做限制
# return request.user.id # 返回已经登录的用户的id,以用户id做限制
views.py
from authenticated.throttle import IpThrottle
# 查看全部和单条。只要登录了谁都可以访问
class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin):
authentication_classes = [LoingAuth, ]
throttle_classes = [IpThrottle] # 访问BookView类做限制
queryset = Book.objects.all()
serializer_class = BookSerializer
settings.py
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_RATES":{
'min_3':'3/m',
},
}
# min_3 就是上面throttle.py.IpThrottle里scope定义的,这个一定要和scope定义的一致
# 3/m 每一分钟访问3次 ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day')
# 如果throttle.py.IpThrottle里还有别的限制的类,如果scope也是为min_3,那它也是每分钟访问3次的限制
超过3次就会报错:

上面的配置为局部配置,也可以设置全局配置
settings.py
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES" : ["authenticated.throttle.IpThrottle"], # 全局配置
"DEFAULT_THROTTLE_RATES":{
'min_3':'3/m',
},
}
# 同样设置了全局,局部的throttle_classes = [IpThrottle]就可以不写了
# 如果只是某个类禁用:
throttle_classes = []
3.1 频率总结
步骤:
第一步:写一个类,继承SimpleRateThrottle,重写类属性:scope,和get_cache_key方法
get_cache_key返回什么,就以什么做限制,
scope配置文件中要用
第二步:在配置文件中配置
settings.py中
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_RATES":{
'min_3':'3/m', # minute_3是scope的字符串,一分钟访问3次
},
}
第三步: 使用
1. 局部使用--》视图类中
class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin):
throttle_classes = [IPThrottle]
2. 全局使用--配置文件中
settings.py中
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES" : ["authenticated.throttle.IpThrottle"],
"DEFAULT_THROTTLE_RATES":{
'min_3':'3/m', # minute_3是scope的字符串,一分钟访问3次
},
}
django-rest-framework 基础三 认证、权限和频率的更多相关文章
- Django REST framework基础:认证、权限、限制
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
- Django Rest framework 框架之认证使用和源码执行流程
用这个框架需要先安装: pip3 install djangorestframework 如果写了一个CBV的东西,继承了View. # 继承Django里面View class APIView(Vi ...
- Django rest framework 基础
01: Django rest framework 基础 1.1 什么是RESTful 1. REST与技术无关,代表的是一种软件架构风格(REST是Representational Stat ...
- Django REST framework 自定义(认证、权限、访问频率)组件
本篇随笔在 "Django REST framework 初识" 基础上扩展 一.认证组件 # models.py class Account(models.Model): &qu ...
- django 之(三) --- 认证|权限
用户模块 登陆注册1:Django2.0 [ 1:N ] user/url.py from django.urls import path from user.views0 import UserT ...
- Django REST framework 之JWT认证
Json Web Token 1.JWT简介 JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 H ...
- Django REST framework 之 API认证
RESTful API 认证 和 Web 应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权 ...
- Django REST framework基础:视图和路由
DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...
- Django REST framework 的TokenAuth认证及外键Serializer基本实现
一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App&q ...
随机推荐
- OpenCV+QT5在Window下的环境配置记录
在安装OpenCV时最需要注意的是,OpenCV库,也就是我们需要的dll和动态库需要我们使用CMake来生成. 虽然在官网上下载得到的文件中已经包含了库文件和.h等头文件,但是在具体开发中编译器编译 ...
- 基本类型数组转List
基本类型数组转List 小数 double[] src = {1.1,2.1,3.1}; List<Double> list = Arrays.stream( src ).boxed(). ...
- BMZCTF 2020祥云杯到点了
2020祥云杯到点了 下载附件得到三个word文档,我们打开第一个文档然后将隐藏文字显示出来 得到提示 我们查看属性应该就是日期了我们先把他记录下来 然后打开第二个文档 输入刚刚的密码 在第二个wor ...
- L298N双H桥集成电路板的双H桥是什么意思?为什么要叫双H桥?L298N工作原理
H桥是一个典型的直流电机控制电路,因为它的电路形状酷似字母H,故得名与"H桥".4个三极管组成H的4条垂直腿,而电机就是H中的横杠. 控制两个三极管的导通来控制电流方向,从而实现电 ...
- circle_clock 简单canvas实现圆弧时钟
渣渣成品图:http://codepen.io/thewindswor... 最近对于圆形有种特别的感情呢...因为写了个cricle_process_bar就像到了用来做时钟大概会比较有趣吧,所以就 ...
- SQL之总结(四)---null问题的处理
概述:如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录.这意味着该字段将以 NULL 值保存. NULL 值的处理方式与其他值不同. NULL 用作未知的或不适 ...
- Unity中让Update中的方法执行一次
Unity中让Update中的方法执行一次 Unity中,很多时候,代码需要放在Update中时刻监测状态,一旦状态符合,又只需要代码执行一次:其实可以通过设置控制量的方式,让代码只执行一次:方法:设 ...
- CCF201604-2俄罗斯方块
问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者没有放置方块.每一轮,都会有一个新的由4个小方 ...
- 界面跳转+信息传递+AS中如何将ADV转移到其他盘中
今日所学:界面跳转 信息传递 遇到的问题: 昨天遇到不能新建java类,在网上百度了很多,大多原因是没有新建java类的模板,但是我有,换了一个新的新建的方式后,发现虽然能建立了,但在测试时还是不能页 ...
- mixin和composition api
1. 这两个都是实现组件逻辑复用的法宝 2. composition api是vue3的, composition api的出现就是解决mixins的不足之处的 一. mixin 回顾下mixin, ...