【技術博客】JWT的認證機制Django項目中應用

開發組在開發過程當中,都不可避免地遇到了一些困難或問題,但都最終想出辦法克服了。咱們認爲這樣的經驗是有必要記錄下來的,所以就有了【技術博客】。html

<br /> # JWT的認證機制Django項目中應用python

這篇技術博客基於軟件工程課程的VisualPytorch之上。本文小部分參考了https://jwt.io/introduction/git

前言-JWT是什麼,爲何用JWT

在作絕大部分數據庫系統時(網站、小程序),登陸註冊確定是一個繞不開的功能。通常來講傳統的解決方案是基於session機制的認證,也就是客戶端發送用戶名密碼給服務器,服務器端驗證後建立一個session,把session的id返回客戶端,客戶端每次請求時帶着session的id以此做爲驗證。github

從個人視角來看主要存在兩個問題:數據庫

(1) 給服務器壓力大

session通常保存在內存中,固然比較大的應用保存在Redis這類數據庫中,經過session_id來作認證增長了訪存次數,影響性能。django

(2) 單點登陸的問題

若是你的應用須要支持經過微信號、QQ號登陸,session_id的方式顯然很成問題,畢竟你不可能拿到騰訊的數據庫裏的內容。小程序

這裏就考慮了使用JWT機制來進行認證。JWT全稱是JSON WEB TOKEN,若是使用JWT進行認證,服務器端不須要保存信息,由於JWT將信息加密到了token裏。用戶只須要每次請求的時候帶着token便可,服務器會本身解密。後端

須要補充的一點是,JWT和session機制並不衝突,若是你的應用對於session有需求,可使用JWT作認證,session作其餘需求。服務器

若是想比較詳細地瞭解JWT,能夠參考RFC7519微信

Django中JWT解決方案

有一個基於Django Restful接口的包能夠用

pip install djangorestframework-jwt

詳細使用方法參照官方文檔

該中間件主要提供了三個接口

#得到token
from rest_framework_jwt.views import obtain_jwt_token
#刷新token
from rest_framework_jwt.views import refresh_jwt_token
#驗證token
from rest_framework_jwt.views import verify_jwt_token

登陸時調用obtain_jwt_token便可。

而對於須要驗證用戶權限的接口,須要在settings.py中添加

'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication'
    ]

隨後在接口層中增長鬚要的權限便可自動利用jwt來驗證(不須要調用上文提到的verify_jwt_token),例如

permission_classes = (permissions.IsAuthenticated,)

如何修改驗證登陸方式

這個其實和JWT無關,和Django有關,但既然都是一個項目下的,不妨多寫一下,以防有需求。

方法重寫Django中User的的後端類中的authenticate方法,而且在settings.py中添加

AUTHENTICATION_BACKENDS = [
    'user.utils.UserAuthBackend',  # 修改auth認證後端類,這裏要寫你本身新寫的驗證類
]

我重寫驗證方法的代碼以下,僅供參考

from django.contrib.auth.backends import ModelBackend
from .models import User
from django.db.models import Q


class UserAuthBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):

        # 郵箱或用戶名登陸
        try:
            user = User.objects.get(Q(username=username) | Q(email=username))
        except User.DoesNotExist:
            return None
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

關與token有效時間與刷新

這個中間價的默認設置一個token有效時間爲300s,token與其子孫token的過時時間爲7天。

也就是說每隔300s都必須刷新當前的token,而隔7天的話刷新也無用必須從新獲取。

須要更改設置能夠參考官方文檔。 <br /><br />

相關文章
相關標籤/搜索