26、Django_rest framework_JWT認(rèn)證授權(quán)

前言

常見的認(rèn)證機(jī)制:

1.Session認(rèn)證
  • 保存在服務(wù)端(會增加服務(wù)器的存儲開銷)
  • 在分布式架構(gòu)中,維護(hù)Session的會話同步比較困難
  • CSRF攻擊(跨站請求)的風(fēng)險
2.Token認(rèn)證

一、JWT/Json Web Token

  • JWT是目前最流行的跨域身份驗(yàn)證解決方案,詳情點(diǎn)擊
  • JWT所使用的用戶模型是Django自帶的用戶模型,也就是auth_user
1、三大部分組成
  • 1.header頭部
    • 使用base64進(jìn)行加密,可以被解密
    • 只用于聲明類型和所使用的加密算法
  • 2.playload載荷
    • 使用base64進(jìn)行加密,可以被解密
    • 存放過期時間、簽發(fā)用戶等非敏感信息
  • 3.signature
    • 對加密后的header+playload使用HS256算法進(jìn)行加密,然后secret加鹽處理
    • SECRET_KEYdjango項(xiàng)目的setting.py中,生成項(xiàng)目時自動生成,也可以更改為動態(tài)形式
1、安裝

pip install djangorestframework-jwt

2、使用

1、在主項(xiàng)目全局指定默認(rèn)使用JWT認(rèn)證,所有項(xiàng)目都需要認(rèn)證;主項(xiàng)目/setting.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 使用JWT Token認(rèn)證      
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        # Basic類型的認(rèn)證(賬號和密碼)
        'rest_framework.authentication.SessionAuthentication',
        # Session會話認(rèn)證
        'rest_framework.authentication.BasicAuthentication',
    ],
}

2、添加登錄路由(JWT提供了登錄視圖),子項(xiàng)目/urls.py

from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('login/', obtain_jwt_token),
]

3、添加主項(xiàng)目路由,主項(xiàng)目/urls.py

urlpatterns = [
    path('users/', include('user.urls'))
]

4、在需要鑒權(quán)認(rèn)證的視圖集進(jìn)行鑒權(quán)級別設(shè)置(不同的視圖頁面會有不同的鑒權(quán)需求),子項(xiàng)目/views.py

# 登錄才可訪問,更多的鑒權(quán)方式可以看permissions中的內(nèi)容
permission_classes = [permissions.IsAuthenticated]

5、啟動項(xiàng)目并訪問即可測試

6、DRF自帶的權(quán)限:
AllowAny
IsAuthenticated
IsAdminUser
IsAuthenticatedOrReadOnly

3、改動
  • 1、修改Token默認(rèn)過期時間(默認(rèn)5分鐘)
    • ./site-packages/rest_framework_jwt/settings.py'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300)設(shè)置為5分鐘
    • 主項(xiàng)目/setting.py中進(jìn)行修改為1天
JWT_AUTH = {    
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1)
}
  • 2、修改登錄后的響應(yīng)內(nèi)容
    • 源代碼只返回token:
def jwt_response_payload_handler(token, user=None, request=None):
    
"""
    Returns the response data for both the login and refresh views.
    Override to return a custom response such as including the
    serialized representation of the User.
    Example:
    def jwt_response_payload_handler(token, user=None, request=None):
        return {
            'token': token,
            'user': UserSerializer(user, context={'request': request}).data
        }
    """
    return {
        'token': token
    }
  • 重寫,返回用戶的id和username,在utils路徑下創(chuàng)建jwt_handler.py對上部分代碼進(jìn)行重寫
def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'token': token,
        'user_id': user.id,
        'username': user.username
    }
  • 主項(xiàng)目/setting.py中進(jìn)行修改,使用重寫后的設(shè)置
JWT_AUTH = {    
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1)
# 原本使用的是源碼,現(xiàn)在修改成重寫后的
'JWT_PAYLOAD_GET_USERNAME_HANDLER': 'utils.jwt_handler.jwt_response_payload_handler'
}

二、httpie工具快速調(diào)試JWT的插件:httpie-jwt-auth

當(dāng)?shù)卿浄祷亓?code>JWT生成的token值后,后面訪問需要鑒權(quán)的視圖請求中,需要帶上固定格式的值:jwt token值,這樣調(diào)試起來很不方便,因?yàn)?code>token值很長(jwt是前綴,可通過設(shè)置JWT_AUTH_HEADER_PREFIX的值進(jìn)行修改)

1、安裝

pip install -U httpie-jwt-auth

2、登錄,獲取到token
http :8000/user/login/ username=xxx password=xxx
3、設(shè)置環(huán)境變量,簡化token的傳遞
export JWT_AUTH_TOKEN = 'your token'
export JWT_AUTH_PREFIX='JWT'
4、發(fā)出帶token的請求
http -A jwt: 8000/user/projects
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容