Django實現JWT - 邱乘屹的個人技術博客


djangorestfarmework-jwt需要結合Django自帶的用戶驗證系統 一起使用

安裝配置

pip install djangorestframework-jwt

配置setting

########### 1、在INSTALLED_APPS中加入'rest_framework.authtoken', #################
INSTALLED_APPS = [
    '''
    'rest_framework.authtoken',  # 
    '''
]

################### 2、配置jwt驗證 ######################
REST_FRAMEWORK = {
    # 身份認證
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
#全局配置JWT驗證設置
'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        ),
}

import datetime

JWT_AUTH = {
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    'JWT_RESPONSE_PAYLOAD_HANDLER':
        'users.views.jwt_response_payload_handler',  # 重新login登錄返回函數
}
AUTH_USER_MODEL='users.User'  # 指定使用users APP中的 model

使用django的user model

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    username = models.CharField(max_length=64, unique=True)
    password = models.CharField(max_length=255)
    phone = models.CharField(max_length=64)
    token = models.CharField(max_length=255)


設置序列化器

from rest_framework_jwt.settings import api_settings
from rest_framework import serializers
from users.models import User

class UserSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()
    phone = serializers.CharField()
    token = serializers.CharField(read_only=True)

    def create(self, data):
        user = User.objects.create(**data)
        user.set_password(data.get('password'))
        user.save()
        # 補充生成記錄登錄狀態的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        return user

代碼實現

from django.shortcuts import render
import json
from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from users.serializers import UserSerializer


# 用戶註冊
class RegisterView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)


# 重新用戶登錄返回函數
url:導入from rest_framework_jwt.views import obtain_jwt_token  配置路由path('login/',obtain_jwt_token)

def jwt_response_payload_handler(token, user=None, request=None):
    '''
    返回的對象
    :param token: jwt生成的token值
    :param user: User對象
    :param request: 請求
    '''
    return {
        'token': token,
        'user': user.username,
        'userid': user.id
    }


# 測試必須攜帶token才能訪問接口
class UserList(APIView):
    permission_classes = [IsAuthenticated]  # 接口中加權限
    authentication_classes = [JSONWebTokenAuthentication]

    def get(self,request, *args, **kwargs):
        print(request.META.get('HTTP_AUTHORIZATION', None))
        return Response({'name':'zhangsan'})
    def post(self,request, *args, **kwargs):
        return Response({'name':'zhangsan'})
        

自定義驗證 自定義驗證方式:要求手機或者郵箱也可作爲登陸手段

AUTHENTICATION_BACKENDS = [
    'userapp.views.UsernameMobileAuthBackend',
]
from django.db.models import Q
from django.contrib.auth.backends import ModelBackend #驗證基類

class UsernameMobileAuthBackend(ModelBackend):
    #重寫驗證方式
    def authenticate(self, request, username=None, password=None, **kwargs):
        user = MyUser.objects.get(Q(username=username) | Q(phone=username))
        if user is not None and user.check_password(password):
            return user
            
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章