網站首頁 編程語言 正文
簡單來講,認證確定了你是誰
權限確定了你能不能訪問某個接口
限制確定了你訪問某個接口的最高頻率
一、認證
身份驗證是將傳?請求與?組標識憑據(例如請求來?的?戶或其簽名的令牌)相關聯的機制。然后權限和限制組件決定是否拒絕這個請求。認證本身不會允許或拒絕傳?的請求,它只是簡單識別請求攜帶的憑證。
REST framwork不僅自己有著開箱即用的驗證方案,還允許你自己實現驗證方案
1.1、自定義認證
要實現?定義的認證?案,要繼承BaseAuthentication
類并且重 寫.authenticate(self, request)
?法。如果認證成功,該?法應返回(user, auth)
的 ?元元組,否則返回None
,還可以拋出AuthenticationFailed
異常
在App下,創建authentications.py
,然后?定義認證類
from django.core.cache import cache
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app.models import Students
class appAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
if not token:
raise AuthenticationFailed('沒有 token')
username = cache.get(token)
if not username:
raise AuthenticationFailed('token 過期')
try:
student = Students.objects.filter(stu_name=username)
if student:
return student, None
else:
return None
except Exception as e:
print(e)
raise AuthenticationFailed('token 不合法')
urls.py
urlpatterns = [
path('getToken/', views.getToken.as_view(), name='getToken'),
path('testToken/',views.testToken.as_view(),name='testToken'),
]
views.py
class getToken(APIView):
# 我們的get請求直接給前端一個token,用于測試
def get(self, request):
username = '123'
token = token_confirm.generate_validate_token(username=username)
mycache = cache.get(token)
if mycache:
token = mycache
else:
cache.set(token, token, settings.CACHE_TIMEOUT)
return HttpResponse('http://127.0.0.1:8000/testToken?token=' + token)
class testToken(APIView):
authentication_classes = (appAuthentication,)
def get(self,request):
return HttpResponse('OK')
我們訪問getToken可以得到需要驗證的網址,然后這個網址登錄可以看到我們登錄后返回的信息,OK
我們也可以進行全局級別的認證,只是這樣的話需要我們配置一下
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'App.authentications.MyAuthentication',
)
}
二、權限控制
權限控制可以限制?戶對于視圖的訪問和對于具體數據對象的訪問
在執?視圖的dispatch()?法前,會先進?視圖訪問權限的判斷
在通過get_object()獲取具體對象時,會進?對象訪問權限的判斷
2.1、系統內置的權限
AllowAny 允許所有?戶
IsAuthenticated 僅通過認證的?戶
IsAdminUser 僅管理員?戶
IsAuthenticatedOrReadOnly 認證的?戶可以完全操作,否則只能get讀取
2.2、自定義權限控制
我們自己寫一個permission.py
# 寫?個繼承?BasePermission
class WomanPerssion(BasePermission):
# 復寫??的has_permission函數
def has_permission(self, request, view):
# request.user是認證后拿到的元組第一個值
print(request.user)
if request.user != None:
# 判斷當前?戶是不是女性用戶
return request.user.stu_gender == 'w'
# 返回True就是驗證通過,返回False就是驗證失敗
return False
我們的視圖函數只需要再加一句話
class testToken(APIView):
authentication_classes = (appAuthentication,)
permission_classes = (WomanPerssion,)
def get(self, request):
return HttpResponse('OK')
如果要進行全局的驗證的話
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'App.authentications.MyAuthentication',
),
"DEFAULT_PERMISSION_CLASSES":
["app.permission.WomanPerssion",]
}
三、節流器
節流類似于權限,?于控制客戶端可以對API發出的請求的速率
mythrottle.py
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
# 轉換頻率每分鐘5次,轉換頻率 = num/duration,其中duration可以是s(秒)、m(分)、h(?時)、d(天)
rate = '5/m'
score = 'vistor'
# 返回?個唯?標示?以區分不同的?戶
def get_cache_key(self, request, view):
return self.get_ident(request) # 返回?戶i
視圖級別的控制
class testToken(APIView):
authentication_classes = (appAuthentication,)
permission_classes = (WomanPerssion,)
throttle_classes = (VisitThrottle,)
def get(self, request):
return HttpResponse('OK')
全局的控制
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'App.authentications.MyAuthentication',
),
"DEFAULT_PERMISSION_CLASSES":
["app.permission.WomanPerssion",],
'DEFAULT_THROTTLE_CLASSES': ['apps.mythrottle.VisitThrottle'],
'DEFAULT_THROTTLE_RATES': {
'vistor': '3/m',
'anon': '10/day',# 匿名?戶
}
}
DEFAULT_THROTTLE_RATES 可以使? second , minute , hour 或 day 來指明周期
3.1、可選限流器
3.1.1、AnonRateThrottle
限制所有匿名未認證?戶,使?IP區分?戶。使? DEFAULT_THROTTLE_RATES[‘anon’] 來設置頻次
3.1.2、UserRateThrottle
限制認證?戶,使?User id 來區分。 使? DEFAULT_THROTTLE_RATES[‘user’] 來設置頻次
3.1.3、ScopedRateThrottle
限制?戶對于每個視圖的訪問頻次,使?ip或user id
eg:
class ContactListView(APIView):
throttle_scope = 'contacts'
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day',
'uploads': '20/day'
}
}
四、分頁Pagination
REST framework提供了分?的?持。 我們可以在配置?件中設置全局的分??式
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10 # 每?數?
}
4.1、自定義分頁類
也可通過?定義Pagination類,來為視圖添加不同分??為。在視圖中通過 pagination_clas 屬性來指明
注意:如果在視圖內關閉分?功能,只需在視圖內設置
pagination_class = None
4.2、PageNumberPagination
前端訪問形式GET http://127.0.0.1:8000/studentView/?page=1
可以在?類中定義的屬性:
page_size 每?數?
page_query_param 前端發送的?數關鍵字名,默認為"page"
page_size_query_param 前端發送的每?數?關鍵字名,默認為None
max_page_size 前端最多能設置的每?數量
serializer.py
from rest_framework import serializers
from app.models import Students
class studentSerializer(serializers.ModelSerializer):
class Meta:
model = Students
# 包含模型中所有字段
fields = '__all__'
models.py
class Students(models.Model):
stu_num = models.CharField(primary_key=True, max_length=8)
stu_name = models.CharField(max_length=40)
stu_gender = models.CharField(max_length=4)
stu_age = models.IntegerField()
cid = models.ForeignKey(Classes, models.DO_NOTHING, db_column='cid', blank=True, null=True)
class Meta:
managed = False
db_table = 'students'
urls.py
urlpatterns = [
path('studentView/', views.studentView.as_view(), name='studentView'),
]
views.py
class studentView(ListAPIView):
queryset = Students.objects.all()
serializer_class = studentSerializer
pagination_class = studentPagination
pagination.py
from rest_framework.pagination import PageNumberPagination
class studentPagination(PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = 1
page_size = 1
page_query_param = 'pagepage'
我們再前端訪問就可以得到我們的數據了
4.3、LimitOffsetPagination
前端的訪問形式GET http://127.0.0.1:8000/studentView/?limit=100&offset=400
可以在?類中定義的屬性:
default_limit 默認限制,默認值與 PAGE_SIZE 設置?直
limit_query_param limit參數名,默認'limit'
offset_query_param offset參數名,默認'offset'
max_limit 最?limit限制,默認None
他的設置方法和前面的一致
五、過濾
對于列表數據可能需要根據字段進?過濾,我們可以通過添加django-fitlter擴展來增強?持。官?地址:https://django-filter.readthedocs.io/en/master/index.html
5.1、安裝
pip install django-filter
5.2、配置
settings.py
INSTALLED_APPS = [
'django_filters', # 需要注冊應?,
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
5.3、視圖設置
class studentView(ListAPIView):
queryset = Students.objects.all()
serializer_class = studentSerializer
filter_fields = ('stu_name', 'stu_gender')
其他的和上面的保持一致,我們訪問下面這個地址
GET http://127.0.0.1:8000/studentView/?stu_gender=w
5.4、自定義過濾類
customfilter.py
import django_filters
from django_filters import rest_framework as filters
from app.models import Students
class studentsFilters(django_filters.FilterSet):
class Meta:
# field_name = "bread" 模型中的字段名; lookup_expr是運算,gte表示 >=
min_read = filters.NumberFilter(field_name="bread", lookup_expr='gte')
ax_read = filters.NumberFilter(field_name="bread", lookup_expr='lte')
model = Students
fields = {
'stu_age': ['icontains'], # 鍵是字段名,列表?是查詢進?運算
}
views.py
class studentView(ListAPIView):
queryset = Students.objects.all()
serializer_class = studentSerializer
filter_class = studentsFilters # 指定過濾類
- field_name 數據庫中字段名
- lookup_expr 操作(和django的orm中運算符?樣) 關系運算符:gte(>=) 、gt(>)、 lte(<=)、 lt(<) 字符串; icontains(忽略??寫,包含)
- model指定模型
- fields可以指定過濾字段
訪問測試:
http://127.0.0.1:8000/studentView/?stu_gender=w
http://127.0.0.1:8000/studentView/?minage=0&maxage=2
這個其實并不重要,我們可以直接數據查詢返回
六、自動生成接口文檔
6.1、安裝
pip install coreapi
6.2、配置
settings.py
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}
6.3、設置接??檔訪問路徑
在總路由中添加接??檔路徑。
?檔路由對應的視圖配置為 rest_framework.documentation.include_docs_urls ,
參數 title 為接??檔?站的標題
6.4、文檔描述說明定義
6.4.1、單一方法視圖
單??法的視圖,可直接使?類視圖的?檔字符串,如
class BookListView(generics.ListAPIView):
"""
返回所有圖書信息.
"""
6.4.1、多個方法視圖
class BookListCreateView(generics.ListCreateAPIView):
"""
get:
返回所有圖書信息.
post:
新建圖書.
"""
6.4.3、視圖集
對于視圖集ViewSet,仍在類視圖的?檔字符串中分開定義,但是應使?action 名稱區分,
class BookInfoViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin, GenericViewSet):
"""
list:
返回圖書列表數據
retrieve:
返回圖書詳情數據
latest:
返回最新的圖書數據
read:
修改圖書的閱讀量
"""
6.4.4、網址訪問
http://127.0.0.1:8000/docs/
原文鏈接:https://blog.csdn.net/weixin_43903639/article/details/122991938
相關推薦
- 2022-07-27 C++詳細講解圖的拓撲排序_C 語言
- 2022-12-23 C++中關于union的使用方法說明_C 語言
- 2022-09-12 C++實例分析組合數的計算與排列組合的產生_C 語言
- 2023-02-25 C和C++如何實現互相調用詳解_C 語言
- 2024-01-31 成功解決 npm ERR! /usr/bin/git ls-remote -h -t git://g
- 2022-09-03 PyQt5實現tableWidget?居中顯示_python
- 2022-04-04 react報錯‘react-scripts‘ 不是內部或外部命令,也不是可運行的程序
- 2023-02-06 Python實現號碼歸屬地查詢功能_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支