日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Token 认证的来龙去脉,DRF认证,DRF权限,DRF限制

發布時間:2024/6/30 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Token 认证的来龙去脉,DRF认证,DRF权限,DRF限制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一章節內容回顧:1.五個葫蘆娃和三行代碼 APIView(views.View)1.封裝了Django的request- request.query_params --> 取URL中的參數- request.data --> 取POST和PUT請求中的數據2. 重寫了View中的dispatch方法dispatch方法 通用類(generics)GenericAPIView- queryset- serializer_class混合類(mixins)- ListModelMixin --> list - CreateModelMixin --> create- RetrieveModelMixin --> retrieve- DestroyModelMixin --> destroy- UpdateModelMixin --> updateCommentView(GenericAPIView, ListModelMixin, CreateModelMixin):def get():return self.list()def post():return self.create()偶數娃:CommentView(ListCreateAPIView):queryset = ...serializer_class = ...奇數娃CommentDetail(RetrieveUpdateDestroyAPIView):queryset = ...serializer_class = ...套娃:Comment(ModelViewSet):queryset = ...serializer_class = ...

APIView和ModelViewSet,該如何取舍。看需求。如果用ModelViewSet,只能按照它要求的格式來走
如果想加入一點個性化的數據,比如{"code":0,"msg":None}還是得需要使用APIView

一、Token 認證的來龍去脈

摘要

Token 是在服務端產生的。如果前端使用用戶名/密碼向服務端請求認證,服務端認證成功,那么在服務端會返回 Token 給前端。前端可以在每次請求的時候帶上 Token 證明自己的合法地位

為什么要用 Token?

而要回答這個問題很簡單——因為它能解決問題!

可以解決哪些問題呢?

  • Token 完全由應用管理,所以它可以避開同源策略

  • Token 可以避免 CSRF 攻擊

  • Token 可以是無狀態的,可以在多個服務間共享

  • Token 是在服務端產生的。如果前端使用用戶名/密碼向服務端請求認證,服務端認證成功,那么在服務端會返回 Token 給前端。前端可以在每次請求的時候帶上 Token 證明自己的合法地位。如果這個 Token 在服務端持久化(比如存入數據庫),那它就是一個永久的身份令牌。

    時序圖表示

    使用 Token 的時序圖如下:

    1)登錄

    2)業務請求

    關于token的詳細信息,請參考鏈接:

    https://blog.csdn.net/maxushan001/article/details/79222271

    ?

    二、DRF 認證

    前提

    還是依然使用昨天的項目about_drf3

    定義一個用戶表和一個保存用戶Token的表,models.py完整代碼下:

    from django.db import models# Create your models here.# 文章表 class Article(models.Model):title = models.CharField(max_length=32, unique=True, error_messages={"unique": "文章標題不能重復"})# 文章發布時間# auto_now每次更新的時候會把當前時間保存create_time = models.DateField(auto_now_add=True)# auto_now_add 第一次創建的時候把當前時間保存update_time = models.DateField(auto_now=True)# 文章的類型type = models.SmallIntegerField(choices=((1, "原創"), (2, "轉載")),default=1)# 來源school = models.ForeignKey(to='School', on_delete=models.CASCADE)# 標簽tag = models.ManyToManyField(to='Tag')# 文章來源表 class School(models.Model):name = models.CharField(max_length=16)# 文章標簽表 class Tag(models.Model):name = models.CharField(max_length=16)# 評論表 class Comment(models.Model):content = models.CharField(max_length=128)article = models.ForeignKey(to='Article', on_delete=models.CASCADE)# 用戶信息表 class UserInfo(models.Model):username = models.CharField(max_length=16, unique=True)password = models.CharField(max_length=32)type = models.SmallIntegerField(choices=((1, '普通用戶'), (2, 'VIP用戶')),default=1)# token class Token(models.Model):token = models.CharField(max_length=128)user = models.OneToOneField(to='UserInfo')

    token單獨分一個表,是因為它是在原有用戶表的功能擴展。不能對一個表無限的增加字段,否則會導致表原來越臃腫

    在前后端分離的架構中,前端使用ajax請求發送給后端,它不能使用cookie/session。那么后端怎么知道這個用戶是否登錄了,是否是VIP用戶呢?使用token就可以解決這個問題!

    ?

    使用2個命令生成表。

    makemigrations 將models.py的變更做記錄
    migrate 將變更記錄轉換為sql語句,并執行

    python manage.py makemigrations python manage.py migrate

    增加2條記錄,使用navicast軟件打開sqlite數據庫,執行以下sql

    INSERT INTO app01_userinfo ("id", "username", "password", "type") VALUES (1, 'zhang', 123, 1); INSERT INTO app01_userinfo ("id", "username", "password", "type") VALUES (2, 'wang', 123, 2);

    app01_token表用來存放token的,它永久的身份令牌。在服務器自動生成的!

    ?

    視圖

    修改views.py,完整代碼如下:

    from django.shortcuts import render, HttpResponse
    from app01 import models
    from app01 import app01_serializers # 導入自定義的序列化
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.views import APIView
    from rest_framework.response import Response
    # Create your views here.

    # 生成Token的函數
    def get_token_code(username):
    """
    根據用戶名和時間戳生成用戶登陸成功的隨機字符串
    :param username: 字符串格式的用戶名
    :return: 字符串格式的Token
    """
    import time
    import hashlib
    timestamp = str(time.time()) # 當前時間戳
    m = hashlib.md5(bytes(username, encoding='utf8'))
    m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytes
    return m.hexdigest()


    # 登陸視圖
    class LoginView(APIView):
    """
    登陸檢測視圖
    1. 接收用戶發過來(POST)的用戶名和密碼數據
    2. 校驗用戶名密碼是否正確
    - 成功就返回登陸成功(發Token)
    - 失敗就返回錯誤提示
    """

    def post(self, request): # POST請求
    res = {"code": 0}
    # 從post里面取數據
    username = request.data.get("username")
    password = request.data.get("password")
    # 去數據庫查詢
    user_obj = models.UserInfo.objects.filter(
    username=username,
    password=password,
    ).first()
    if user_obj:
    # 登陸成功
    # 生成Token
    token = get_token_code(username)
    # 將token保存
    # 用user=user_obj這個條件去Token表里查詢
    # 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據
    models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)
    # 將token返回給用戶
    res["token"] = token
    else:
    # 登錄失敗
    res["code"] = 1
    res["error"] = '用戶名或密碼錯誤'
    return Response(res)


    class CommentViewSet(ModelViewSet):
    queryset = models.Comment.objects.all()
    serializer_class = app01_serializers.CommentSerializer

    from django.shortcuts import render, HttpResponse from app01 import models from app01 import app01_serializers # 導入自定義的序列化 from rest_framework.viewsets import ModelViewSet from rest_framework.views import APIView from rest_framework.response import Response # Create your views here.# 生成Token的函數 def get_token_code(username):"""根據用戶名和時間戳生成用戶登陸成功的隨機字符串:param username: 字符串格式的用戶名:return: 字符串格式的Token"""import timeimport hashlibtimestamp = str(time.time()) # 當前時間戳m = hashlib.md5(bytes(username, encoding='utf8'))m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytesreturn m.hexdigest()# 登陸視圖 class LoginView(APIView):"""登陸檢測視圖1. 接收用戶發過來(POST)的用戶名和密碼數據2. 校驗用戶名密碼是否正確- 成功就返回登陸成功(發Token)- 失敗就返回錯誤提示"""def post(self, request): # POST請求res = {"code": 0}# 從post里面取數據username = request.data.get("username")password = request.data.get("password")# 去數據庫查詢user_obj = models.UserInfo.objects.filter(username=username,password=password,).first()if user_obj:# 登陸成功# 生成Tokentoken = get_token_code(username)# 將token保存# 用user=user_obj這個條件去Token表里查詢# 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)# 將token返回給用戶res["token"] = tokenelse:# 登錄失敗res["code"] = 1res["error"] = '用戶名或密碼錯誤'return Response(res)class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializer

    路由

    修改app01_urls.py,刪除多余的代碼

    from django.conf.urls import url
    from app01 import views

    urlpatterns = [
    url(r'login/$', views.LoginView.as_view()),
    ]

    from rest_framework.routers import DefaultRouter

    router = DefaultRouter()
    # 注冊路由,表示路徑comment對應視圖函數CommentViewSet
    router.register(r'comment', views.CommentViewSet)
    urlpatterns += router.urls

    from django.conf.urls import url from app01 import viewsurlpatterns = [url(r'login/$', views.LoginView.as_view()), ]from rest_framework.routers import DefaultRouterrouter = DefaultRouter() # 注冊路由,表示路徑comment對應視圖函數CommentViewSet router.register(r'comment', views.CommentViewSet) urlpatterns += router.urls

    使用postman發送post登錄

    查看返回結果,code為0表示登錄成功,并返回一個token

    查看表app01_token,就會多一條記錄

    ?

    postman訪問評論,它是可以任意訪問的

    ?

    DRF認證源碼流程

    DRF認證源碼流程,請參考鏈接:

    https://www.cnblogs.com/haiyan123/p/8419872.html? (后半段沒有寫)

    https://www.cnblogs.com/derek1184405959/p/8712206.html? (后半段寫了)

    ?

    執行流程圖解

    圖片來源:?https://www.cnblogs.com/renpingsheng/p/7897192.html

    ?

    定義一個認證類

    現在有一個需求,只有登錄的用戶,才能對評論做修改

    在app01(應用名)目錄下創建目錄utils,在此目錄下創建auth.py

    """ 自定義的認證類都放在這里 """ from rest_framework.authentication import BaseAuthentication from app01 import models from rest_framework.exceptions import AuthenticationFailedclass MyAuth(BaseAuthentication):def authenticate(self, request): # 必須要實現此方法if request.method in ['POST', 'PUT', 'DELETE']:token = request.data.get("token")# 去數據庫查詢有沒有這個tokentoken_obj = models.Token.objects.filter(token=token).first()if token_obj:# token_obj有2個屬性,詳見models.py中的Token。# return后面的代碼,相當于分別賦值。例如a=1,b=2等同于a,b=1,2# return多個值,返回一個元組#在rest framework內部會將這兩個字段賦值給request,以供后續操作使用return token_obj.user, token # self.user, self.token = token_obj.user, tokenelse:raise AuthenticationFailed('無效的token')else:return None, None

    視圖級別認證

    修改views.py,完整代碼如下:

    from django.shortcuts import render, HttpResponse
    from app01 import models
    from app01 import app01_serializers # 導入自定義的序列化
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py

    # Create your views here.

    # 生成Token的函數
    def get_token_code(username):
    """
    根據用戶名和時間戳生成用戶登陸成功的隨機字符串
    :param username: 字符串格式的用戶名
    :return: 字符串格式的Token
    """
    import time
    import hashlib
    timestamp = str(time.time()) # 當前時間戳
    m = hashlib.md5(bytes(username, encoding='utf8'))
    m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytes
    return m.hexdigest()


    # 登陸視圖
    class LoginView(APIView):
    """
    登陸檢測視圖
    1. 接收用戶發過來(POST)的用戶名和密碼數據
    2. 校驗用戶名密碼是否正確
    - 成功就返回登陸成功(發Token)
    - 失敗就返回錯誤提示
    """

    def post(self, request): # POST請求
    res = {"code": 0}
    # 從post里面取數據
    username = request.data.get("username")
    password = request.data.get("password")
    # 去數據庫查詢
    user_obj = models.UserInfo.objects.filter(
    username=username,
    password=password,
    ).first()
    if user_obj:
    # 登陸成功
    # 生成Token
    token = get_token_code(username)
    # 將token保存
    # 用user=user_obj這個條件去Token表里查詢
    # 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據
    models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)
    # 將token返回給用戶
    res["token"] = token
    else:
    # 登錄失敗
    res["code"] = 1
    res["error"] = '用戶名或密碼錯誤'
    return Response(res)


    class CommentViewSet(ModelViewSet):
    queryset = models.Comment.objects.all()
    serializer_class = app01_serializers.CommentSerializer
    authentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth

    from django.shortcuts import render, HttpResponse from app01 import models from app01 import app01_serializers # 導入自定義的序列化 from rest_framework.viewsets import ModelViewSet from rest_framework.views import APIView from rest_framework.response import Response from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py# Create your views here.# 生成Token的函數 def get_token_code(username):"""根據用戶名和時間戳生成用戶登陸成功的隨機字符串:param username: 字符串格式的用戶名:return: 字符串格式的Token"""import timeimport hashlibtimestamp = str(time.time()) # 當前時間戳m = hashlib.md5(bytes(username, encoding='utf8'))m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytesreturn m.hexdigest()# 登陸視圖 class LoginView(APIView):"""登陸檢測視圖1. 接收用戶發過來(POST)的用戶名和密碼數據2. 校驗用戶名密碼是否正確- 成功就返回登陸成功(發Token)- 失敗就返回錯誤提示"""def post(self, request): # POST請求res = {"code": 0}# 從post里面取數據username = request.data.get("username")password = request.data.get("password")# 去數據庫查詢user_obj = models.UserInfo.objects.filter(username=username,password=password,).first()if user_obj:# 登陸成功# 生成Tokentoken = get_token_code(username)# 將token保存# 用user=user_obj這個條件去Token表里查詢# 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)# 將token返回給用戶res["token"] = tokenelse:# 登錄失敗res["code"] = 1res["error"] = '用戶名或密碼錯誤'return Response(res)class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializerauthentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth

    ?發送一個空的post請求,返回結果如下:

    發送一個錯誤的token

    返回結果:

    發送正確的token

    返回結果,出現以下信息,說明已經通過了認證

    全局級別認證

    要想讓每一個視圖都要認證,可以在settings.py中配置

    REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ] }

    修改views.py,注釋掉CommentViewSet中的authentication_classes

    class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializer# authentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth

    再次測試上面的3種請求方式,效果同上!

    二、DRF權限

    權限源碼流程

    請參考鏈接:

    http://www.cnblogs.com/derek1184405959/p/8722212.html

    ?

    舉例1

    只有VIP用戶才能看的內容。

    ?

    自定義一個權限類

    has_permission

    在目錄app01-->utils下面新建文件permission.py

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):def has_permission(self, request, view):"""判斷該用戶有沒有權限"""# 判斷用戶是不是VIP用戶# 如果是VIP用戶就返回True# 如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷啦....')print(request)print(request.user)return True

    視圖級別配置

    修改views.py,指定permission_classes

    from django.shortcuts import render, HttpResponse from app01 import models from app01 import app01_serializers # 導入自定義的序列化 from rest_framework.viewsets import ModelViewSet from rest_framework.views import APIView from rest_framework.response import Response from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py from app01.utils.permission import MyPermission# Create your views here.# 生成Token的函數 def get_token_code(username):"""根據用戶名和時間戳生成用戶登陸成功的隨機字符串:param username: 字符串格式的用戶名:return: 字符串格式的Token"""import timeimport hashlibtimestamp = str(time.time()) # 當前時間戳m = hashlib.md5(bytes(username, encoding='utf8'))m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytesreturn m.hexdigest()# 登陸視圖 class LoginView(APIView):"""登陸檢測視圖1. 接收用戶發過來(POST)的用戶名和密碼數據2. 校驗用戶名密碼是否正確- 成功就返回登陸成功(發Token)- 失敗就返回錯誤提示"""def post(self, request): # POST請求res = {"code": 0}# 從post里面取數據username = request.data.get("username")password = request.data.get("password")# 去數據庫查詢user_obj = models.UserInfo.objects.filter(username=username,password=password,).first()if user_obj:# 登陸成功# 生成Tokentoken = get_token_code(username)# 將token保存# 用user=user_obj這個條件去Token表里查詢# 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)# 將token返回給用戶res["token"] = tokenelse:# 登錄失敗res["code"] = 1res["error"] = '用戶名或密碼錯誤'return Response(res)class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializer# authentication_classes = [MyAuth, ] # 局部使用認證方法MyAuthpermission_classes = [MyPermission, ] # 局部使用權限方法

    發送get請求

    查看Pycharm控制臺輸出:

    我要進行自定義的權限判斷啦.... <rest_framework.request.Request object at 0x000002576A780FD0> None

    發現用戶為None

    ?

    普通用戶

    發送post請求,寫一個正確的token,用zhang用戶的token

    查看Pycharm控制臺輸出:

    我要進行自定義的權限判斷啦.... <rest_framework.request.Request object at 0x000002576A9852B0> UserInfo object

    此時得到了一個用戶對象

    修改permission.py,獲取用戶名以及用戶類型

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):def has_permission(self, request, view):"""判斷該用戶有沒有權限"""# 判斷用戶是不是VIP用戶# 如果是VIP用戶就返回True# 如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷啦....')print(request)print(request.user.username)print(request.user.type)return True

    再次發送同樣的post請求,再次查看pycharm控制臺輸出

    <rest_framework.request.Request object at 0x000001D893AC4048> zhang 1

    居然得到了zhang和1。為什么呢?為什么request.user.username就能得到用戶名呢?

    我來大概解釋一下,先打開這篇文章:

    https://www.cnblogs.com/derek1184405959/p/8712206.html

    我引用里面幾句話

    Request有個user方法,加 @property 表示調用user方法的時候不需要加括號“user()”,可以直接調用:request.user

    在rest framework內部會將這兩個字段賦值給request,以供后續操作使用

    return (token_obj.user,token_obj)

    上面的return的值,來源于app01\utils\auth.py?里面的MyAuth類中的return?token_onj.user , token?簡單來說,通過認證之后,它會request進行再次封裝,所以調用request.user時,得到了一個對象,這個對象就是執行models.Token.objects.filter(token=token).first()結果

    如果ORM沒有查詢出結果,它就是一個匿名用戶!

    ?

    修改permission.py ,如果VIP返回True,否則返回False

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):def has_permission(self, request, view):"""判斷用戶有沒有權限:param request::param view::return:"""#判斷用戶是不是VIP用戶#如果是VIP用戶就返回True#如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷....')print(request.user.username)print(request.user.type)if request.user.type == 2: #是VIP用戶return Trueelse:return False

     修改settings.py,關閉全局級別認證

     

    REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ] } REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ] }

    ?

    使用VIP用戶wang登錄

    使用VIP用戶wang登錄

    查看返回結果,它返回wang的token

    查看表app01_token,它現在有2個記錄了

    ?

    復制zhang的token,發送一條評論

    查看返回結果,提示您沒有執行此操作的權限

    英文看不懂,沒關系,定義成中文就行了

    修改permission.py,定義message

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):message = '您沒有執行此操作的權限!'def has_permission(self, request, view):"""判斷該用戶有沒有權限"""# 判斷用戶是不是VIP用戶# 如果是VIP用戶就返回True# 如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷啦....')# print(request)print(request.user.username)print(request.user.type)if request.user.type == 2: # 是VIP用戶return Trueelse:return False

    VIP用戶

    將token改成VIP用戶測試

    查看返回結果

    ?

    修改permission.py,定義發送類型

    修改permission.py,定義發送類型

    """
    自定義的權限類
    """
    from rest_framework.permissions import BasePermission


    class MyPermission(BasePermission):
    message = '您沒有執行此操作的權限!'
    def has_permission(self, request, view):
    """
    判斷該用戶有沒有權限
    """
    # 判斷用戶是不是VIP用戶
    # 如果是VIP用戶就返回True
    # 如果是普通用戶就返回False
    print('我要進行自定義的權限判斷啦....')

    if request.method in ['POST', 'PUT', 'DELETE']:
    print(request.user.username)
    print(request.user.type)
    if request.user.type == 2: # 是VIP用戶
    return True
    else:
    return False
    else:
    return True

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):message = '您沒有執行此操作的權限!'def has_permission(self, request, view):"""判斷該用戶有沒有權限"""# 判斷用戶是不是VIP用戶# 如果是VIP用戶就返回True# 如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷啦....')if request.method in ['POST', 'PUT', 'DELETE']:print(request.user.username)print(request.user.type)if request.user.type == 2: # 是VIP用戶return Trueelse:return Falseelse:return True

    發送正確的值

    查看返回結果

    查看表app01_comment記錄

    ?

    全局級別設置

    修改settings.py,增加一行

    REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ]"DEFAULT_PERMISSION_CLASSES": ["app01.utils.permission.MyPermission", ] }

    修改views.py,注釋局部的

    from django.shortcuts import render, HttpResponse from app01 import models from app01 import app01_serializers # 導入自定義的序列化 from rest_framework.viewsets import ModelViewSet from rest_framework.views import APIView from rest_framework.response import Response from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py from app01.utils.permission import MyPermission# Create your views here.# 生成Token的函數 def get_token_code(username):"""根據用戶名和時間戳生成用戶登陸成功的隨機字符串:param username: 字符串格式的用戶名:return: 字符串格式的Token"""import timeimport hashlibtimestamp = str(time.time()) # 當前時間戳m = hashlib.md5(bytes(username, encoding='utf8'))m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytesreturn m.hexdigest()# 登陸視圖 class LoginView(APIView):"""登陸檢測視圖1. 接收用戶發過來(POST)的用戶名和密碼數據2. 校驗用戶名密碼是否正確- 成功就返回登陸成功(發Token)- 失敗就返回錯誤提示"""def post(self, request): # POST請求res = {"code": 0}# 從post里面取數據username = request.data.get("username")password = request.data.get("password")# 去數據庫查詢user_obj = models.UserInfo.objects.filter(username=username,password=password,).first()if user_obj:# 登陸成功# 生成Tokentoken = get_token_code(username)# 將token保存# 用user=user_obj這個條件去Token表里查詢# 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)# 將token返回給用戶res["token"] = tokenelse:# 登錄失敗res["code"] = 1res["error"] = '用戶名或密碼錯誤'return Response(res)class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializerauthentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth# permission_classes = [MyPermission, ] # 局部使用權限方法

     

    驗證

    使用普通用戶測試

    ?查看返回結果

    ?

    舉例2

    只要評論的作者是自己,就可以刪除,否則不行!

    只要評論的作者是自己,就可以刪除,否則不行!

    表結構

    修改models.py,在評論表中,增加一個字段user

    class Comment(models.Model):content = models.CharField(max_length=128)article = models.ForeignKey(to='Article', on_delete=models.CASCADE)user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, null=True) class Comment(models.Model):content = models.CharField(max_length=128)article = models.ForeignKey(to='Article', on_delete=models.CASCADE)user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, null=True)

    使用2個命令生成表。

    python manage.py makemigrations python manage.py migrate

    修改表,增加2個user_id

    has_object_permission

    修改permission.py,增加has_object_permission

    它比上面的has_permission方法多了一個obj
    它是操作的對象,比如評論對象

    """
    自定義的權限類
    """
    from rest_framework.permissions import BasePermission


    class MyPermission(BasePermission):
    message = '您沒有執行此操作的權限!'
    def has_permission(self, request, view):
    """
    判斷該用戶有沒有權限
    """
    # 判斷用戶是不是VIP用戶
    # 如果是VIP用戶就返回True
    # 如果是普通用戶就返回False
    print('我要進行自定義的權限判斷啦....')
    return True
    # if request.method in ['POST', 'PUT', 'DELETE']:
    # print(request.user.username)
    # print(request.user.type)
    # if request.user.type == 2: # 是VIP用戶
    # return True
    # else:
    # return False
    # else:
    # return True

    def has_object_permission(self, request, view, obj):
    """
    判斷當前評論用戶的作者是不是你當前的用戶
    只有評論的作者才能刪除自己的評論
    """
    print('這是在自定義權限類中的has_object_permission')
    print(obj.id)
    if request.method in ['PUT', 'DELETE']:
    if obj.user == request.user:
    # 當前要刪除的評論的作者就是當前登陸的用戶
    return True
    else:
    return False
    else:
    return True

    """ 自定義的權限類 """ from rest_framework.permissions import BasePermissionclass MyPermission(BasePermission):message = '您沒有執行此操作的權限!'def has_permission(self, request, view):"""判斷該用戶有沒有權限"""# 判斷用戶是不是VIP用戶# 如果是VIP用戶就返回True# 如果是普通用戶就返回Falseprint('我要進行自定義的權限判斷啦....')return True# if request.method in ['POST', 'PUT', 'DELETE']:# print(request.user.username)# print(request.user.type)# if request.user.type == 2: # 是VIP用戶# return True# else:# return False# else:# return Truedef has_object_permission(self, request, view, obj):"""判斷當前評論用戶的作者是不是你當前的用戶只有評論的作者才能刪除自己的評論"""print('這是在自定義權限類中的has_object_permission')print(obj.id)if request.method in ['PUT', 'DELETE']:if obj.user == request.user:# 當前要刪除的評論的作者就是當前登陸的用戶return Trueelse:return Falseelse:return True

    ?使用普通用戶的token發送delete類型的請求

    查看返回結果?

    ?使用VIP用戶的token發送

    ?查看返回結果,為空,表示刪除成功

    ?

    ?查看表app01_comment,發現少了一條記錄

    ?

    四、DRF限制

    限制也稱之為節流

    DRF節流源碼分析

    請參考鏈接:

    http://www.cnblogs.com/derek1184405959/p/8722638.html

    自定義限制類

    對IP做限制,60秒只能訪問3次

    ?

    在about_drf\app01\utils下面創建throttle.py

    """
    自定義的訪問限制類
    """
    from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
    import time

    D = {} # {'127.0.0.1': [1533302442, 1533302439,...]}


    class MyThrottle(BaseThrottle):

    def allow_request(self, request, view):
    """
    返回True就放行,返回False表示被限制了...
    """
    # 1. 獲取當前訪問的IP
    ip = request.META.get("REMOTE_ADDR")
    print('這是自定義限制類中的allow_request')
    print(ip)
    # 2. 獲取當前的時間
    now = time.time()
    # 判斷當前ip是否有訪問記錄
    if ip not in D:
    D[ip] = [] # 初始化一個空的訪問歷史列表
    # 高端騷操作
    history = D[ip]
    while history and now - history[-1] > 10:
    history.pop()
    # 判斷最近一分鐘的訪問次數是否超過了閾值(3次)
    if len(history) >= 3:
    return False
    else:
    # 把這一次的訪問時間加到訪問歷史列表的第一位
    D[ip].insert(0, now)
    return True

    """ 自定義的訪問限制類 """ from rest_framework.throttling import BaseThrottle, SimpleRateThrottle import timeD = {} # {'127.0.0.1': [1533302442, 1533302439,...]}class MyThrottle(BaseThrottle):def allow_request(self, request, view):"""返回True就放行,返回False表示被限制了..."""# 1. 獲取當前訪問的IPip = request.META.get("REMOTE_ADDR")print('這是自定義限制類中的allow_request')print(ip)# 2. 獲取當前的時間now = time.time()# 判斷當前ip是否有訪問記錄if ip not in D:D[ip] = [] # 初始化一個空的訪問歷史列表# 高端騷操作history = D[ip]while history and now - history[-1] > 10:history.pop()# 判斷最近一分鐘的訪問次數是否超過了閾值(3次)if len(history) >= 3:return Falseelse:# 把這一次的訪問時間加到訪問歷史列表的第一位D[ip].insert(0, now)return True

    代碼解釋:

    request.META.get("REMOTE_ADDR")? 獲取遠程IP

    D? 存儲的值,類似于

    "192.168.1.2":["17:06:45","12:04:03","12:04:01"]

    最后一個元素,就是最先開始的時間

    for循環列表,不能對列表做更改操作!所以使用while循環

    while history and now - history[-1] > 10:history.pop()

    history是歷史列表,history[-1] 表示列表最后一個元素

    history and now - history[-1] > 10 表示當歷史列表中有元素,并且當前時間戳減去最后一個元素的時間戳大于10的時候,執行history.pop(),表示刪除最后一個元素

    當歷史列表為空時,或者小于差值小于10的時候,結束循環。

    ?

    視圖使用

    修改views.py

    修改views.py

    from django.shortcuts import render, HttpResponse
    from app01 import models
    from app01 import app01_serializers # 導入自定義的序列化
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py
    from app01.utils.permission import MyPermission
    from app01.utils.throttle import MyThrottle

    # Create your views here.

    # 生成Token的函數
    def get_token_code(username):
    """
    根據用戶名和時間戳生成用戶登陸成功的隨機字符串
    :param username: 字符串格式的用戶名
    :return: 字符串格式的Token
    """
    import time
    import hashlib
    timestamp = str(time.time()) # 當前時間戳
    m = hashlib.md5(bytes(username, encoding='utf8'))
    m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytes
    return m.hexdigest()


    # 登陸視圖
    class LoginView(APIView):
    """
    登陸檢測視圖
    1. 接收用戶發過來(POST)的用戶名和密碼數據
    2. 校驗用戶名密碼是否正確
    - 成功就返回登陸成功(發Token)
    - 失敗就返回錯誤提示
    """

    def post(self, request): # POST請求
    res = {"code": 0}
    # 從post里面取數據
    username = request.data.get("username")
    password = request.data.get("password")
    # 去數據庫查詢
    user_obj = models.UserInfo.objects.filter(
    username=username,
    password=password,
    ).first()
    if user_obj:
    # 登陸成功
    # 生成Token
    token = get_token_code(username)
    # 將token保存
    # 用user=user_obj這個條件去Token表里查詢
    # 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據
    models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)
    # 將token返回給用戶
    res["token"] = token
    else:
    # 登錄失敗
    res["code"] = 1
    res["error"] = '用戶名或密碼錯誤'
    return Response(res)


    class CommentViewSet(ModelViewSet):
    queryset = models.Comment.objects.all()
    serializer_class = app01_serializers.CommentSerializer
    authentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth
    # permission_classes = [MyPermission, ] # 局部使用權限方法
    throttle_classes = [MyThrottle, ] # 局部使用限制方法

    from django.shortcuts import render, HttpResponse from app01 import models from app01 import app01_serializers # 導入自定義的序列化 from rest_framework.viewsets import ModelViewSet from rest_framework.views import APIView from rest_framework.response import Response from app01.utils.auth import MyAuth # app01.utils.auth表示app01目錄下的utils下的auth.py from app01.utils.permission import MyPermission from app01.utils.throttle import MyThrottle# Create your views here.# 生成Token的函數 def get_token_code(username):"""根據用戶名和時間戳生成用戶登陸成功的隨機字符串:param username: 字符串格式的用戶名:return: 字符串格式的Token"""import timeimport hashlibtimestamp = str(time.time()) # 當前時間戳m = hashlib.md5(bytes(username, encoding='utf8'))m.update(bytes(timestamp, encoding='utf8')) # update必須接收一個bytesreturn m.hexdigest()# 登陸視圖 class LoginView(APIView):"""登陸檢測視圖1. 接收用戶發過來(POST)的用戶名和密碼數據2. 校驗用戶名密碼是否正確- 成功就返回登陸成功(發Token)- 失敗就返回錯誤提示"""def post(self, request): # POST請求res = {"code": 0}# 從post里面取數據username = request.data.get("username")password = request.data.get("password")# 去數據庫查詢user_obj = models.UserInfo.objects.filter(username=username,password=password,).first()if user_obj:# 登陸成功# 生成Tokentoken = get_token_code(username)# 將token保存# 用user=user_obj這個條件去Token表里查詢# 如果有記錄就更新defaults里傳的參數, 沒有記錄就用defaults里傳的參數創建一條數據models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj)# 將token返回給用戶res["token"] = tokenelse:# 登錄失敗res["code"] = 1res["error"] = '用戶名或密碼錯誤'return Response(res)class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializerauthentication_classes = [MyAuth, ] # 局部使用認證方法MyAuth# permission_classes = [MyPermission, ] # 局部使用權限方法throttle_classes = [MyThrottle, ] # 局部使用限制方法

    使用postman發送GET請求

    瘋狂的點擊SEND按鈕,多發送幾次

    提示請求達到了限制

    ?等待十幾秒,就可以訪問了

    全局使用

    修改settings.py

    REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ],#"DEFAULT_PERMISSION_CLASSES": ["app01.utils.permission.MyPermission", ],"DEFAULT_THROTTLE_CLASSES": ["app01.utils.throttle.MyThrottle", ] } REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ],#"DEFAULT_PERMISSION_CLASSES": ["app01.utils.permission.MyPermission", ],"DEFAULT_THROTTLE_CLASSES": ["app01.utils.throttle.MyThrottle", ] }

    修改views.py,注釋掉代碼

    class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializerauthentication_classes = [MyAuth, ] # 局部使用認證方法MyAuthpermission_classes = [MyPermission, ] # 局部使用權限方法# throttle_classes = [MyThrottle, ] # 局部使用限制方法 class CommentViewSet(ModelViewSet):queryset = models.Comment.objects.all()serializer_class = app01_serializers.CommentSerializerauthentication_classes = [MyAuth, ] # 局部使用認證方法MyAuthpermission_classes = [MyPermission, ] # 局部使用權限方法# throttle_classes = [MyThrottle, ] # 局部使用限制方法

    再次測試,效果同上!

    ?

    使用內置限制類

    修改about_drf\app01\utils\throttle.py

    """
    自定義的訪問限制類
    """
    from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
    # import time
    #
    # D = {} # {'127.0.0.1': [1533302442, 1533302439,...]}
    #
    #
    # class MyThrottle(BaseThrottle):
    #
    # def allow_request(self, request, view):
    #
    # """
    # 返回True就放行,返回False表示被限制了...
    # """
    # # 1. 獲取當前訪問的IP
    # ip = request.META.get("REMOTE_ADDR")
    # print('這是自定義限制類中的allow_request')
    # print(ip)
    # # 2. 獲取當前的時間
    # now = time.time()
    # # 判斷當前ip是否有訪問記錄
    # if ip not in D:
    # D[ip] = [] # 初始化一個空的訪問歷史列表
    # # 高端騷操作
    # history = D[ip]
    # while history and now - history[-1] > 10:
    # history.pop()
    # # 判斷最近一分鐘的訪問次數是否超過了閾值(3次)
    # if len(history) >= 3:
    # return False
    # else:
    # # 把這一次的訪問時間加到訪問歷史列表的第一位
    # D[ip].insert(0, now)
    # return True

    class MyThrottle(SimpleRateThrottle):

    scope = "rate" # rate是名字,可以隨便定義!

    def get_cache_key(self, request, view):
    return self.get_ident(request)

    """ 自定義的訪問限制類 """ from rest_framework.throttling import BaseThrottle, SimpleRateThrottle # import time # # D = {} # {'127.0.0.1': [1533302442, 1533302439,...]} # # # class MyThrottle(BaseThrottle): # # def allow_request(self, request, view): # # """ # 返回True就放行,返回False表示被限制了... # """ # # 1. 獲取當前訪問的IP # ip = request.META.get("REMOTE_ADDR") # print('這是自定義限制類中的allow_request') # print(ip) # # 2. 獲取當前的時間 # now = time.time() # # 判斷當前ip是否有訪問記錄 # if ip not in D: # D[ip] = [] # 初始化一個空的訪問歷史列表 # # 高端騷操作 # history = D[ip] # while history and now - history[-1] > 10: # history.pop() # # 判斷最近一分鐘的訪問次數是否超過了閾值(3次) # if len(history) >= 3: # return False # else: # # 把這一次的訪問時間加到訪問歷史列表的第一位 # D[ip].insert(0, now) # return Trueclass MyThrottle(SimpleRateThrottle):scope = "rate" # rate是名字,可以隨便定義!def get_cache_key(self, request, view):return self.get_ident(request)

    注意:scope是關鍵字參數

    get_cache_key 的名字不能變動

    self.get_ident(request)? 表示遠程IP地址

    ?

    全局配置

    修改settings.py

    REST_FRAMEWORK = {# 表示app01-->utils下的auth.py里面的MyAuth類# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ]"DEFAULT_PERMISSION_CLASSES": ["app01.utils.permission.MyPermission", ],"DEFAULT_THROTTLE_CLASSES": ["app01.utils.throttle.MyThrottle", ],"DEFAULT_THROTTLE_RATES": {"rate": "3/m",} }

    注意:rate對應的是throttle.py里面MyThrottle定義的scope屬性的值

    3/m 表示1分鐘3次

    ?

    再次測試,效果如下:

    它還會返回倒計時的時間!

      

      

      

    轉載于:https://www.cnblogs.com/haowen980/p/9416531.html

    總結

    以上是生活随笔為你收集整理的Token 认证的来龙去脉,DRF认证,DRF权限,DRF限制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产高清一 | 91麻豆精品国产91 | 探花视频在线观看免费版 | 日本韩国精品在线 | 国产精品久久久久久久久久三级 | 91天天操 | 久久久久久久综合色一本 | 国产精品高潮久久av | 就操操久久 | 日韩大片在线看 | 久久综合精品国产一区二区三区 | 一区二区三区在线播放 | 91亚洲精品国偷拍 | 国产精品久久久久久久7电影 | 人人干狠狠干 | 综合色影院 | 亚洲精品一区二区久 | 88av网站 | 免费日韩视 | 狠狠干 狠狠操 | 国产精品久久一区二区三区不卡 | 香蕉视频在线免费 | 国产视频在线免费观看 | 国产亚洲在线观看 | 国内视频1区 | 色婷婷99| www亚洲国产 | 欧美久久久久久久久 | 激情视频91 | 欧美另类老妇 | 激情视频免费在线观看 | 天天搞天天干 | 麻豆视频免费播放 | 国产精品久久久久久久久久久免费 | 激情伊人五月天久久综合 | 麻豆精品在线视频 | av在线免费观看黄 | 91精品视频免费看 | 9999亚洲 | 久久激情五月婷婷 | 久久久久久久久久久网 | 国产精品久久电影观看 | 黄色毛片视频免费观看中文 | 久久一区国产 | 97干com | 欧美激情精品久久久久久免费印度 | 国产精品成人a免费观看 | 亚洲精品在线资源 | 亚洲狠狠丁香婷婷综合久久久 | 毛片永久新网址首页 | 丁香久久五月 | 99久热在线精品视频 | 久草视频中文 | 久久99中文字幕 | 国产精品99在线观看 | 九九热免费观看 | 国产视频1 | 国产精品中文在线 | 2023av在线| 色婷婷亚洲婷婷 | 国产91影视 | 国产涩涩在线观看 | 麻豆传媒一区二区 | 一区二区不卡在线观看 | 黄色片免费看 | 国产精品岛国久久久久久久久红粉 | 日韩免费高清 | 欧美午夜精品久久久久久孕妇 | 美女久久久久久久久久 | 久草在线最新 | 日韩精品免费在线视频 | 国产又粗又猛又黄又爽的视频 | 久久精品久久久久久久 | 97国产在线播放 | 91超碰免费在线 | 天天干天天搞天天射 | 就色干综合 | 干干干操操操 | 亚洲码国产日韩欧美高潮在线播放 | 国产精品成人一区二区 | 91人人爽久久涩噜噜噜 | 中文国产字幕在线观看 | 亚洲国产欧美一区二区三区丁香婷 | 亚洲午夜精品久久久 | 国产成人精品综合久久久久99 | 黄色日视频 | 爱情影院aqdy鲁丝片二区 | 亚洲精品成人网 | 激情网综合 | 亚洲人人爱 | 久久特级毛片 | 99久久婷婷国产精品综合 | 欧美日韩国产一区 | 91三级在线观看 | 亚洲在线成人精品 | 欧美欧美 | 久久激情日本aⅴ | 国产精品xxxx18a99 | 亚洲精品午夜一区人人爽 | 狠狠操夜夜 | 视色网站| 天天插天天干天天操 | 亚洲精品乱码久久久久久久久久 | 久热色超碰 | 在线免费观看视频 | 中文字幕第一页在线视频 | 国产精品 日韩 欧美 | 视频91在线| 国产精品区一区 | 久草精品视频 | 99精品免费久久久久久久久日本 | 成人黄色小说在线观看 | 超碰97在线看| 在线播放日韩av | 精品播放 | 国产成在线观看免费视频 | 色资源网在线观看 | 免费看污网站 | 久久久久久久久久国产精品 | 成人久久精品视频 | 99国内精品久久久久久久 | 天天射天天 | 国产视频中文字幕 | 欧美日韩免费观看一区二区三区 | 在线视频 国产 日韩 | 久草剧场| 69视频永久免费观看 | 欧美91片 | 欧美精品亚洲精品 | 国产在线色视频 | 国产黄色理论片 | 最近中文字幕在线中文高清版 | 国产成人免费av电影 | 亚洲日本va午夜在线影院 | 一级免费av| 在线看成人 | 九九导航 | 国产精品一区二区久久精品爱微奶 | 午夜视频日本 | 亚洲黄色免费网站 | 日本一区二区三区免费观看 | 91亚色免费视频 | 亚洲视频播放 | 国产精品av电影 | 一级片视频免费观看 | 91看片看淫黄大片 | 免费一级日韩欧美性大片 | 国产精品区一区 | 97免费视频在线播放 | 免费在线观看av不卡 | 米奇影视7777| 国产一级做a爱片久久毛片a | 91丨九色丨蝌蚪丰满 | 亚洲免费色 | 欧美日韩视频在线播放 | 五月婷婷激情综合网 | 日本99久久| 综合网天天射 | 狠狠色狠狠色综合日日92 | 99精品视频免费全部在线 | 欧美精品亚州精品 | 中文字幕精品一区久久久久 | 丁香婷婷激情国产高清秒播 | 激情欧美一区二区免费视频 | 中文字幕影片免费在线观看 | 久久久久观看 | 国产精品成人久久久 | 亚洲精品久久在线 | 色丁香综合 | 国产精品成人久久久久久久 | 成人免费 在线播放 | 丁香综合激情 | 日韩动漫免费观看高清完整版在线观看 | 欧美精品久久久久久久久久久 | 中文字幕在线观看免费观看 | 久久综合五月天婷婷伊人 | 日韩免费在线网站 | 91喷水| 三级av免费看 | 天天摸日日摸人人看 | 国产亚洲欧美在线视频 | 在线导航av | 久久不射电影院 | 亚洲欧洲久久久 | www.com在线观看 | 久久久久黄 | 国产黄色高清 | 精品久久久久久亚洲综合网 | 91九色视频网站 | 日韩三级在线观看 | a精品视频| 亚洲成人网av| 经典三级一区 | 午夜精品久久一牛影视 | 91桃色免费观看 | 日韩高清不卡一区二区三区 | 成人av网页 | 国产黄色片免费 | 天天操夜夜逼 | www.777奇米| 四虎成人精品永久免费av九九 | 亚洲男女精品 | 中文在线最新版天堂 | 国产码电影| www.午夜| 91精品国产麻豆国产自产影视 | 婷婷播播网 | 日日操天天操夜夜操 | 亚洲午夜久久久久久久久久久 | 亚洲人成在线电影 | 亚洲激情在线观看 | 国产午夜精品福利视频 | 国产视频色 | 91精品亚洲影视在线观看 | 亚洲少妇激情 | 天天干夜夜夜 | 深爱激情站 | 色婷婷狠狠操 | 中文字幕精品www乱入免费视频 | 日韩高清在线一区二区 | av成人资源 | 天天干天天操天天射 | 国产精品一区二区久久精品爱微奶 | 午夜 久久 tv | av黄色免费看 | 日日干激情五月 | 国内精品视频久久 | 免费三级影片 | 天天干天天玩天天操 | 在线导航福利 | 久久成人精品电影 | 婷婷午夜| 亚洲乱码中文字幕综合 | 免费精品视频 | av中文天堂在线 | 亚洲japanese制服美女 | 天天爽天天摸 | 丁香花在线视频观看免费 | 国产高清专区 | 999久久a精品合区久久久 | 久久99久久99精品免费看小说 | 欧美日韩免费看 | 偷拍精品一区二区三区 | 热久久这里只有精品 | 韩国av一区二区三区在线观看 | 国产美女被啪进深处喷白浆视频 | 5月丁香婷婷综合 | 亚洲影院天堂 | 日韩亚洲国产中文字幕 | av视屏在线 | 久久久www成人免费精品张筱雨 | 亚洲精品一区二区三区新线路 | 九色精品免费永久在线 | 日韩一区二区在线免费观看 | 国内久久精品视频 | 2019av在线视频 | 91麻豆精品国产自产在线 | 国产自制av| 欧美精品乱码久久久久久按摩 | 欧美最新另类人妖 | 久久免费国产电影 | 国产一二三区在线观看 | 日韩在线视频看看 | 国产福利在线不卡 | 午夜三级影院 | 18av在线视频 | 成人va在线观看 | 国产精品一区二区久久国产 | 色91在线| 97超视频免费观看 | 在线国产福利 | 激情综合狠狠 | 狠狠干夜夜 | 国产人在线成免费视频 | 国产亚洲免费的视频看 | 国产精品短视频 | 天天干 夜夜操 | av网站手机在线观看 | 天天操天天干天天插 | 99精品视频中文字幕 | 亚州精品天堂中文字幕 | 九9热这里真品2 | 欧美日本一二三 | 人人精品 | www.五月婷婷 | 亚洲一级二级三级 | 久久久午夜电影 | 亚洲天堂网视频在线观看 | 免费在线观看av网址 | 日韩a免费| 天堂av在线网 | 色婷婷午夜 | 国产一区二区精品在线 | 中文字幕在线播放日韩 | 久久久久www | 亚洲做受高潮欧美裸体 | 久久久999免费视频 日韩网站在线 | 胖bbbb搡bbbb擦bbbb| 成人av播放 | 精品久久久一区二区 | 国产精品女人久久久久久 | 国产99久久久久久免费看 | 天天干.com | 国产探花 | 欧美综合色在线图区 | 日韩在线免费高清视频 | 91高清免费看 | 一区二区三区四区五区六区 | 中文字幕电影在线 | 国产精品综合久久 | 亚州免费视频 | 中国成人一区 | 国产老熟| 五月婷婷黄色 | 日韩精品免费专区 | 九色视频网站 | 日韩欧美xxx | 国产视频一级 | 国产精品影音先锋 | 免费的成人av | 超碰在线最新地址 | 91av在线电影| 伊人久久影视 | 国产玖玖视频 | 免费看污网站 | 美女黄视频免费 | 91在线超碰 | 手机av资源 | 欧美一区二区三区在线观看 | 色在线视频 | 国产精品色视频 | 久久精品99久久久久久2456 | 国产成人精品一区二三区 | 99热精品视 | 99热最新在线 | 午夜精品一区二区三区免费视频 | 欧亚日韩精品一区二区在线 | 久久久黄视频 | 欧美人zozo | 欧美另类tv | 国产精品美女999 | 成年人黄色免费视频 | 亚州日韩中文字幕 | 久久国产成人午夜av影院宅 | 国产精品久久网 | 亚洲国产欧美一区二区三区丁香婷 | 婷婷精品国产欧美精品亚洲人人爽 | 又色又爽又黄高潮的免费视频 | 久久久久久久18 | 国产婷婷视频在线 | 欧美日韩aa | 国产一二区免费视频 | 国产高清视频在线播放 | 国产一区二区在线播放 | 亚洲精品99久久久久中文字幕 | 久久久久久久久黄色 | 久久久国产精品视频 | 日韩免费观看一区二区 | 日本精品va在线观看 | 日韩在线观看视频一区二区三区 | 欧美一级日韩三级 | 日本中文字幕在线观看 | 九九热只有这里有精品 | 国产精品成人一区 | 色网址99| 在线观看黄色的网站 | 91网在线观看| 在线免费精品视频 | 91精品国产91p65| 久久国精品 | 亚洲精品 在线视频 | 亚欧日韩av| 992tv又爽又黄的免费视频 | 久久久久国产免费免费 | 在线观看免费av网 | 久久久精品影视 | 操夜夜操 | av一区二区在线观看中文字幕 | 国产精品欧美在线 | 久久精品观看 | 成人av网站在线 | 亚洲一级黄色片 | 人人干人人艹 | 免费在线观看成年人视频 | 国产高清久久久 | 九九久久国产 | 日韩在线电影一区二区 | 97视频人人澡人人爽 | 久久久亚洲影院 | 免费网站黄色 | 亚洲成人高清在线 | 日韩免费电影一区二区三区 | 超级碰99| 色爱成人网 | 日本中文在线播放 | 粉嫩一区二区三区粉嫩91 | 国产精品v欧美精品 | av九九九| 最近2019年日本中文免费字幕 | 99久久99精品 | 欧美综合色在线图区 | 国产高清av免费在线观看 | 97久久精品午夜一区二区 | 青青河边草观看完整版高清 | 91精品视频在线观看免费 | 亚洲国产成人精品在线观看 | 亚洲欧洲精品一区二区 | 久久久久高清毛片一级 | 四虎影视欧美 | 亚洲成av片人久久久 | 天天操天天拍 | 碰超在线观看 | 精品久久久网 | 91激情视频在线播放 | 久草精品视频在线看网站免费 | 日韩a在线| 又色又爽又激情的59视频 | 狠狠干电影 | 操操操人人人 | 黄色成年 | 一区二区 不卡 | 免费在线观看不卡av | 国产日韩在线看 | 成年人在线观看 | 九九久久影视 | 在线播放你懂 | 日韩在线中文字幕 | www.色国产 | 91在线视频在线 | 久久9视频 | 日本激情视频中文字幕 | 五月天.com | 17videosex性欧美 | 91自拍视频在线观看 | 国产专区视频在线 | 亚洲精品在线视频播放 | 国产一区精品在线观看 | 日韩欧美在线视频一区二区三区 | 三级a毛片| 天天操夜操 | 国产精品久久久久久久免费观看 | 久久综合九色综合97_ 久久久 | 日韩av电影中文字幕在线观看 | jizzjizzjizz亚洲 | 国产a级片免费观看 | 亚洲精品男人的天堂 | 日韩免费二区 | 精品国产一区在线观看 | 在线视频观看你懂的 | 日韩成人免费电影 | 在线影院av | 中文字幕在线观看免费高清完整版 | 一区二区三区在线观看免费 | 热久久免费国产视频 | 在线成人小视频 | 一色屋精品视频在线观看 | 五月丁色| 国产视频久久久久 | 欧美国产日韩在线视频 | h动漫中文字幕 | 久久人人97超碰精品888 | 国产精品每日更新 | 精品一区二区三区四区在线 | 粉嫩一区二区三区粉嫩91 | 国产精品久久二区 | 日韩精品免费一区二区三区 | 少妇做爰k8经典 | 国产一区二区三区免费在线观看 | 91视频-88av | 日韩夜夜爽| 草免费视频 | 黄色小说视频在线 | 97在线免费视频观看 | 婷婷av在线| 久久久免费播放 | 国产精品久久久久影视 | 91人人澡人人爽人人精品 | 人人爽人人做 | 99久久久久| 天天干,天天操,天天射 | 麻豆一区在线观看 | 国产中文字幕一区 | 日日弄天天弄美女bbbb | 亚洲人成在 | 国产午夜精品福利视频 | 久av在线 | 国产91探花| 日p视频在线观看 | 国产精品毛片一区视频 | 狠狠狠色丁香综合久久天下网 | a黄在线观看 | 亚洲婷婷在线视频 | 亚洲午夜久久久久久久久久久 | 日韩精品首页 | 欧美久草在线 | 蜜臀av性久久久久av蜜臀三区 | 综合国产在线观看 | 天天操天天爱天天爽 | 4hu视频 | 成人激情开心网 | 久久 一区| 日韩一区二区三区高清在线观看 | 在线免费观看一区二区三区 | 在线观看视频你懂 | 狠狠干狠狠插 | 国内视频在线 | 日韩精品久久久免费观看夜色 | 成人国产精品电影 | 久久久色| 国产午夜精品一区二区三区四区 | 国产糖心vlog在线观看 | 狠狠色丁香婷婷综合欧美 | 中文字幕高清视频 | 日日摸日日添夜夜爽97 | 精品久久久久一区二区国产 | 国产精品网址在线观看 | 有没有在线观看av | 精品国产一区二区三区久久久 | 美女网色 | 国产精品久久久久久久久久久杏吧 | 狠狠的日 | 日韩高清免费在线 | 狠狠操狠狠操 | 亚洲区另类春色综合小说 | 在线观看中文字幕dvd播放 | 免费成人黄色av | 中文字幕你懂的 | 97超碰国产精品女人人人爽 | 精品国产一区二区三区久久久蜜臀 | 天天操夜夜操夜夜操 | 91在线日本| 在线免费性生活片 | 免费av网站在线看 | 国产精品国产三级国产不产一地 | 亚洲国产av精品毛片鲁大师 | www久久久 | 国产美女视频黄a视频免费 久久综合九色欧美综合狠狠 | 成人久久亚洲 | 欧美一区二视频在线免费观看 | 四虎免费av| 日韩动态视频 | 久久精品国亚洲 | 91在线播| 一区二区精品 | 美女免费视频一区二区 | 国产精品白丝jk白祙 | 91日韩免费| 激情一区二区三区欧美 | 毛片无卡免费无播放器 | 狠狠色伊人亚洲综合网站野外 | 国产精品久久久久久久久久久久冷 | 在线久热 | 国产成人777777 | 日韩成人免费在线电影 | 日韩精品视频在线观看免费 | 色www免费视频 | 国产大陆亚洲精品国产 | 国产精品久久久久久久久婷婷 | 久久久久久伊人 | 缴情综合网五月天 | 亚洲精品h | 日韩欧美精品在线观看视频 | 久久99热久久99精品 | 国产精品嫩草55av | 久久九九久久 | 最近免费在线观看 | 国内精自线一二区永久 | 91桃色视频| 亚洲第二色| 国产女人40精品一区毛片视频 | 啪啪午夜免费 | 国产午夜麻豆影院在线观看 | 天天综合网 天天综合色 | 最新国产在线 | 国产精品久久久久久久久费观看 | 亚洲精品免费在线观看 | 91在线区| 黄色片毛片 | 成人免费一区二区三区在线观看 | 国产亚洲精品久久久久久移动网络 | 国产在线精品一区二区不卡了 | 国产99免费视频 | 国产精品美女视频网站 | 久久免费中文视频 | 伊人天天操 | 日日夜夜网站 | 亚洲日韩中文字幕 | 激情欧美丁香 | 久久久穴 | 国产白浆视频 | 国产成人精品三级 | 天天综合网入口 | 麻豆久久久久 | aⅴ精品av导航 | 亚洲成aⅴ人片久久青草影院 | 国产在线p | 国产一区欧美日韩 | 色欲综合视频天天天 | 久久婷婷精品 | 国产日韩欧美视频在线观看 | 日本中文字幕免费观看 | 天天天天天天操 | 亚洲欧美日韩一级 | 黄色av电影免费观看 | 国产欧美在线一区 | 亚洲在线a | 久久久久久久久久久网站 | 国内久久久 | 国产在线精品一区二区不卡了 | 国产精品区免费视频 | 亚洲香蕉在线观看 | 久久草av| 国产美女精品在线 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 日女人免费视频 | 免费看的黄色录像 | 日韩av手机在线观看 | 国内少妇自拍视频一区 | 欧美电影在线观看 | 色狠狠综合天天综合综合 | www.av免费 | 久久试看 | 成人视屏免费看 | 国产亚洲精品久久网站 | 伊人狠狠色丁香婷婷综合 | 黄色免费视频在线观看 | 超碰97在线资源站 | 亚洲成人一区 | 在线看黄网站 | 91精品秘密在线观看 | 国产韩国精品一区二区三区 | 麻豆免费观看视频 | 久色伊人| 夜夜躁日日躁狠狠久久av | www视频免费在线观看 | 玖玖在线免费视频 | 99国产精品| 国产精品亚洲人在线观看 | 九九综合在线 | 国产免费叼嘿网站免费 | 国产精品福利av | 国产精品黄色影片导航在线观看 | 国内一级片在线观看 | 999成人网 | 久久99精品久久久久婷婷 | 国产一级精品视频 | 午夜影院在线观看18 | 久久综合婷婷国产二区高清 | 99久久99久久精品免费 | 日韩美av在线 | 欧美日韩高清一区二区三区 | 日日噜噜噜噜夜夜爽亚洲精品 | 欧美日韩国产精品久久 | 国产视频精选在线 | 免费观看福利视频 | 超碰在线最新网址 | 中文字幕亚洲国产 | 欧美一区二区三区免费看 | av东方在线| 欧美日韩在线观看不卡 | 欧美精品视 | 色五月成人 | 国产精品久久久久毛片大屁完整版 | 国产99久久99热这里精品5 | 999久久精品 | 丁香av| 久久久久久高潮国产精品视 | 天天看天天干 | 国产高清av | 成人一区在线观看 | 亚洲精品成人av在线 | 亚洲午夜电影网 | 久操视频在线播放 | 免费高清在线观看电视网站 | 深爱激情五月婷婷 | 日韩爱爱片 | 激情视频91 | 91色蜜桃| 国产一线二线三线性视频 | 亚洲 欧美 国产 va在线影院 | 欧美人交a欧美精品 | 久久99久久久久久 | 蜜臀精品久久久久久蜜臀 | 亚洲视屏在线播放 | 精品亚洲视频在线观看 | 日韩电影在线一区 | 亚洲欧美国内爽妇网 | 99热亚洲精品 | 91精品久久久久久久91蜜桃 | www.福利| 婷婷综合 | 国产精品99久久久久久武松影视 | 天天色天天射综合网 | 超碰在线观看99 | 国内精品久久久久久 | 2023av在线| 婷婷色六月天 | 精品国产美女 | 日韩精品久久久久久久电影99爱 | 亚洲无吗天堂 | av短片在线观看 | 日韩综合一区二区三区 | 国产高清 不卡 | 亚洲日本va午夜在线电影 | 中文字幕免费国产精品 | 一区二区电影在线观看 | 亚州精品在线视频 | 国产亚洲精品久久久久久久久久久久 | 欧美午夜寂寞影院 | 97视频在线看 | 成年人视频在线免费观看 | 91免费在线 | 久久久久国产精品www | 日韩av电影中文字幕在线观看 | 久久午夜电影网 | 天天综合91 | 成人18视频| 色综合久久久久综合 | 欧美日韩网站 | 日韩视频一二三区 | 亚洲清纯国产 | 国产一区二区视频在线 | 婷婷丁香花五月天 | 免费久久99精品国产婷婷六月 | 中文久草 | 中文字幕在线网 | 日日成人网 | 99久久精品免费看国产麻豆 | 久久一区精品 | 婷婷www| 探花视频免费观看高清视频 | 久久视频在线观看免费 | 999在线视频 | 韩日精品中文字幕 | 最新av网址在线观看 | 97色噜噜| 国产中文字幕免费 | 国产成人久久av977小说 | 日韩在线免费看 | 免费高清在线视频一区· | 日日夜夜天天久久 | 综合色站| 国产成人亚洲在线观看 | 国产高清永久免费 | 蜜臀久久99静品久久久久久 | 91一区二区三区在线观看 | 久久久久激情 | 成人黄色国产 | 视频二区 | 日韩在线视频在线观看 | 国产精品不卡在线 | 黄色www| 视频一区在线免费观看 | 九九热免费视频在线观看 | 国产成人精品一区二区在线观看 | 色国产视频| 中文字幕一区二区三区在线观看 | 亚洲va天堂va欧美ⅴa在线 | 青青河边草免费 | 中文字幕一二三区 | 久久成年人网站 | 免费看三级网站 | 精品一区二区6 | 91人网站 | 一区二区国产精品 | 九九热精品视频在线观看 | 99电影 | 中国精品少妇 | 中文字幕中文字幕在线中文字幕三区 | 中文字幕日韩高清 | 久久艹欧美 | 亚洲涩综合 | 黄色aaaaa| 香蕉影视 | 国产婷婷在线观看 | 亚洲成a人片77777kkkk1在线观看 | 中文字幕在| bbb搡bbb爽爽爽 | 99久久精品电影 | 亚洲天堂精品视频 | 成人黄色大片网站 | 免费观看性生交大片3 | 91麻豆高清视频 | 99爱精品视频 | 日韩在线视频观看免费 | 成年人天堂com | 亚洲黄网站 | 最近中文字幕高清字幕在线视频 | 人人玩人人添人人澡超碰 | 国产精品免费大片视频 | 不卡的av电影 | 岛国片在线 | 日韩免费高清 | 97色狠狠| 91精品老司机久久一区啪 | 91久久精品日日躁夜夜躁国产 | 精品在线观看免费 | 日韩欧美视频免费看 | 91视频一8mav | 亚洲欧美婷婷六月色综合 | 亚洲一级片在线观看 | 热久久免费视频精品 | 99色99| 97色涩| 99精品在线看 | 五月婷婷香蕉 | 国产精品一区二区三区视频免费 | 国产精品久久久久久久久久直播 | 国产一区二区免费在线观看 | 中文电影网| 久操视频在线免费看 | 国产精品久久婷婷六月丁香 | 国产精品嫩草影院9 | 色噜噜噜| 在线免费观看黄色av | 91人人插| 久青草影院| 国产精品久久久久免费观看 | 97精品国自产拍在线观看 | 亚洲国内精品在线 | 日本视频精品 | 婷婷亚洲最大 | 香蕉视频在线网站 | 一区二区三区观看 | 日日爱网站 | 亚洲色图色 | 亚洲更新最快 | 国产精品久久久久免费 | 97碰碰精品嫩模在线播放 | av三级在线免费观看 | 国产精品第二页 | 日日干av | 一区二区不卡视频在线观看 | 黄色毛片观看 | 爱情影院aqdy鲁丝片二区 | 免费看污的网站 | 欧美大jb | 中文字幕一区二区三区乱码在线 | 中文字幕在线播放第一页 | 色播五月激情综合网 | 久久免费资源 | 一区二区三区不卡在线 | 亚洲女人天堂成人av在线 | 免费一级片久久 | 91精品国产综合久久福利不卡 | 在线免费视频一区 | 日韩一级黄色片 | 国产精品普通话 | 激情图片区 | 亚洲成人高清在线 | 麻豆免费在线播放 | 国产精品一区二区你懂的 | 久久69av | 国产高清不卡av | 啪嗒啪嗒免费观看完整版 | 久久99久久精品 | 三级在线视频播放 | 色综合婷婷久久 | 亚洲一二三久久 | 亚州日韩中文字幕 | 日韩色综合网 | 亚洲午夜小视频 | 91精选在线观看 | 视频一区在线播放 | 在线91视频| 国产一级免费在线 | 制服丝袜在线91 | 中文字幕在线播放一区二区 | 国产一卡在线 | 久久久久久久久久久久av | 日韩精品免费 | 日韩视频免费看 | 丁香花在线观看视频在线 | 岛国av在线免费 | 伊人影院av | 亚洲高清视频在线观看免费 | 成年人免费观看国产 | 99精品视频观看 | 操操操av| 91成人免费 | 欧洲色吧 | 久久久久久久久久久久影院 | 在线观看黄色国产 | 亚洲另类视频在线观看 | 亚洲欧美国内爽妇网 | adn—256中文在线观看 | 国产资源中文字幕 | 中文字幕日韩高清 | 久久99网| 久久久免费电影 | 中文字幕亚洲精品在线观看 | 国产99re| 99久久精品久久久久久清纯 | 天天色天天骑天天射 | 色婷婷88av视频一二三区 | 狠狠干天天色 | 国产91成人 | 欧美ⅹxxxxxx | 亚洲欧美国产日韩在线观看 | 久久人人爽视频 | 在线国产高清 | 中文字幕乱码在线播放 | 欧美日韩在线精品 | 亚洲一级电影在线观看 | 人人擦| 狠狠色狠狠色终合网 | 91精品视频免费在线观看 | 国产精品久久久久久妇 | 五月婷婷中文字幕 | 色播激情五月 | av福利在线 | 五月亚洲婷婷 | 天天做日日爱夜夜爽 | 久精品在线观看 | 亚洲精品系列 | 精品国产成人av | 国产在线国偷精品产拍 | 国产中文a | 中文字幕高清视频 | 日韩欧美国产激情在线播放 | 成人免费在线播放视频 | 中文字幕在线观看免费高清完整版 | 午夜精品视频一区二区三区在线看 | 久久黄色影院 | japanesefreesex中国少妇 | 成年人免费看的视频 | 99色| 日韩黄色免费 | 国产精品欧美日韩 | 国产在线97| 一级黄色片在线免费看 | 日韩电影在线观看中文字幕 | 亚洲免费激情 | 日韩资源在线 | 少妇视频一区 | 中文字幕日本电影 | 婷婷电影网| 欧美成天堂网地址 | 精品五月天| 亚洲我射av| 久草9视频 | 视频直播国产精品 | 中文字幕精 | 日韩一级黄色大片 | 一区二区三区在线免费观看 | 91福利专区| 精品久久五月天 | 国产一级三级 | 国产精品久久久久久久久大全 | 成年人免费av | 中文字幕色在线 | www.超碰97.com | 日韩精品不卡在线 | 激情视频在线观看网址 | 激情五月***国产精品 | 丁香婷婷综合激情五月色 | 日韩另类在线 | 九九九电影免费看 | 在线看岛国av | 免费观看久久久 | 久久久久免费精品国产 | 欧美一级性视频 | av资源免费看 | 日产中文字幕 | 免费成人短视频 | 色综合久久88色综合天天人守婷 | 欧美一级片在线 | 日本精品一区二区三区在线播放视频 | 九色最新网址 | 国产精品大片免费观看 | 国产精品麻豆视频 | 日韩免费视频在线观看 | 色五月激情五月 | 激情五月在线 | 亚洲情感电影大片 | 天堂av在线7 | 久久久久北条麻妃免费看 | 97超碰中文字幕 | 亚洲国产成人久久 | 欧美乱码精品一区 | 日b视频在线观看网址 | 在线观看91av | 久久色网站 | 99九九视频 | 永久精品视频 | 亚洲人成人天堂h久久 | 中文字幕亚洲五码 | 久久久久久久久久电影 | 国产精品美女www爽爽爽视频 | 91免费试看 | 久久久福利视频 | 91久久久久久久一区二区 | 综合久久久 | 日韩av片无码一区二区不卡电影 | 91精品第一页 | 亚洲日本一区二区在线 | 久久亚洲综合国产精品99麻豆的功能介绍 | 麻豆小视频在线观看 |