drf認證組件、權限組件、jwt認證、簽發、jwt框架使用

1、註冊接口

urls.py

router.register('register', views.RegisterViewSet, 'register')
from rest_framework_jwt.views import ObtainJSONWebToken
urlpatterns = [
    url('^login/$', ObtainJSONWebToken.as_view()),
    url('', include(router.urls))
]

views.py

from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework import mixins
from . import models, serializers

class RegisterViewSet(GenericViewSet, mixins.CreateModelMixin):
    queryset = models.User.objects.filter(is_active=True).all()
    serializer_class = serializers.RegisterSerializer

serializers.py

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from . import models


class RegisterSerializer(serializers.ModelSerializer):
    re_password = serializers.CharField(write_only=True, min_length=8, max_length=18)
    class Meta:
        model = models.User
        fields = ('username', 'password', 're_password', 'mobile')
        extra_kwargs = {
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 18
            }
        }

    # username和mobile能夠自定義局部鉤子校驗(省略)

    def validate(self, attrs):
        password = attrs.get('password')
        re_password = attrs.pop('re_password')
        if password != re_password:
            raise ValidationError({'re_password': 'password confirm error'})
        return attrs

    # 須要重寫create,建立用戶須要密文
    def create(self, validated_data):
        return models.User.objects.create_user(**validated_data)

2、登陸接口

調用寫好的登陸接口便可算法

from rest_framework_jwt.views import ObtainJSONWebToken
urlpatterns = [
    url('^login/$', ObtainJSONWebToken.as_view()),

    url('', include(router.urls))
]

3、用戶中心接口(權限校驗)

urls.py

router.register('user/center', views.UserCenterViewSet, 'center')

views.py

from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly
class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin):
    permission_classes = [IsAuthenticated, ]
    queryset = models.User.objects.filter(is_active=True).all()
    serializer_class = serializers.UserCenterSerializer
'''
AllowAny:遊客也可訪問
IsAuthenticated:必須登陸的用戶  纔有權限
IsAdminUser:必須登陸,而且時後臺用戶  纔有權限
IsAuthenticatedOrReadOnly:讀能夠(get請求能夠),可是寫(post請求)必須登陸
'''

serializers.py

class UserCenterSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ('username', 'mobile', 'icon', 'email')

4、圖書資源接口

urls.py

router.register('books', views.BookViewSet, 'book')

views.py

class BookViewSet(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializer

serializers.py

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ('name', )

5、認證組件

重點

"""
1)認證規則
2)如何自定義認證類
3)咱們通常不須要自定義認證類,在settings中全局配置第三方 jwt 認證組件提供的認證類便可
"""

自定義認證類

"""
1)自定義認證類,繼承 BaseAuthentication 類
2)必須重寫 authenticate(self, request) 方法
    沒有認證信息,返回None:匿名用戶(遊客) => 匿名用戶request.user也有值,就是"匿名對象(Anonymous)"
    有認證信息,且經過,返回(user, token):合法用戶 => user對象會存到request.user中
    有認證信息,不經過,拋異常:非法用戶
"""

6、權限組件

重點

"""
1)權限規則
2)如何自定義權限類
3)咱們通常在視圖類中局部配置drf提供的權限類,可是也會自定義權限類完成局部配置
"""

自定義權限類

"""
1)自定義權限類,繼承 BasePermission 類
2)必須重寫 has_permission(self, request, view): 方法
    設置權限條件,條件經過,返回True:有權限
    設置權限條件,條件失敗,返回False:有權限
    
3)drf提供的權限類:
AllowAny:匿名與合法用戶均可以
IsAuthenticated:必須登陸,只有合法用戶能夠
IsAdminUser:必須是admin後臺用戶
IsAuthenticatedOrReadOnly:匿名只讀(get請求能夠)(post請求不能夠),合法用戶無限制
"""

7、jwt認證示意圖

""" jwt優點
1)沒有數據庫寫操做,高效
2)服務器不存token,低耗
3)簽發校驗都是算法,集羣
"""


8、 jwt認證算法:簽發與校驗

"""
1)jwt分三段式:頭.體.簽名 (head.payload.sgin)
2)頭和體是可逆加密,讓服務器能夠反解出user對象;簽名是不可逆加密,保證整個token的安全性的
3)頭體簽名三部分,都是採用json格式的字符串,進行加密,可逆加密通常採用base64算法,不可逆加密通常採用hash(md5)算法
4)頭中的內容是基本信息:公司信息、項目組信息、token採用的加密方式信息
{
    "company": "公司信息",
    ...
}
5)體中的內容是關鍵信息:用戶主鍵、用戶名、簽發時客戶端信息(設備號、地址)、過時時間
{
    "user_id": 1,
    ...
}
6)簽名中的內容時安全信息:頭的加密結果 + 體的加密結果 + 服務器不對外公開的安全碼 進行md5加密
{
    "head": "頭的加密字符串",
    "payload": "體的加密字符串",
    "secret_key": "安全碼"
}
"""

簽發:根據登陸請求提交來的 帳號 + 密碼 + 設備信息 簽發 token

"""
1)用基本信息存儲json字典,採用base64算法加密獲得 頭字符串
2)用關鍵信息存儲json字典,採用base64算法加密獲得 體字符串
3)用頭、體加密字符串再加安全碼信息存儲json字典,採用hash md5算法加密獲得 簽名字符串

帳號密碼就能根據User表獲得user對象,造成的三段字符串用 . 拼接成token返回給前臺
"""

校驗:根據客戶端帶token的請求 反解出 user 對象

"""
1)將token按 . 拆分爲三段字符串,第一段 頭加密字符串 通常不須要作任何處理
2)第二段 體加密字符串,要反解出用戶主鍵,經過主鍵從User表中就能獲得登陸用戶,過時時間和設備信息都是安全信息,確保token沒過時,且時同一設備來的
3)再用 第一段 + 第二段 + 服務器安全碼 不可逆md5加密,與第三段 簽名字符串 進行碰撞校驗,經過後才能表明第二段校驗獲得的user對象就是合法的登陸用戶
"""

9、drf項目的jwt認證開發流程(重點)

"""
1)用帳號密碼訪問登陸接口,登陸接口邏輯中調用 簽發token 算法,獲得token,返回給客戶端,客戶端本身存到cookies中

2)校驗token的算法應該寫在認證類中(在認證類中調用),全局配置給認證組件,全部視圖類請求,都會進行認證校驗,因此請求帶了token,就會反解出user對象,在視圖類中用request.user就能訪問登陸的用戶

注:登陸接口須要作 認證 + 權限 兩個局部禁用
"""

10、drf-jwt框架基本使用

安裝(終端)

>: pip install djangorestframework-jwt

簽發token

(登陸接口):視圖類已經寫好了,配置一下路由就行(urls.py)數據庫

from rest_framework_jwt.views import ObtainJSONWebToken
# api/urls.py
urlpatterns = [
    # ...
    url('^login/$', ObtainJSONWebToken.as_view()),
]

# Postman請求:/api/login/,提供username和password便可

校驗token(認證組件)

認證類已經寫好了,全局配置一下認證組件就好了(settings.py)django

# drf-jwt的配置
import datetime
JWT_AUTH = {
    # 配置過時時間
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}


# drf配置(把配置放在最下方)
REST_FRAMEWORK = {
    # 自定義三大認證配置類們
    'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'],
    # 'DEFAULT_PERMISSION_CLASSES': [],
    # 'DEFAULT_THROTTLE_CLASSES': [],
}

設置須要登陸才能訪問的接口進行測試(views.py)

from rest_framework.permissions import IsAuthenticated
class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin):
    # 設置必須登陸才能訪問的權限類
    permission_classes = [IsAuthenticated, ]

    queryset = models.User.objects.filter(is_active=True).all()
    serializer_class = serializers.UserCenterSerializer

測試訪問登陸認證接口(Postman)

"""
1)用 {"username": "你的用戶", "password": "你的密碼"} 訪問 /api/login/ 接口等到 token 字符串

2)在請求頭用 Authorization 攜帶 "jwt 登陸獲得的token" 訪問 /api/user/center/1/ 接口訪問我的中心
"""

相關文章
相關標籤/搜索