Django JWT 重寫認證 使用者表 實現登入註冊
安裝配置
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
註冊路遊
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
from django.contrib import admin
from django.urls import path,include
from syl.settings import *
urlpatterns = [
path('admin/', admin.site.urls),
path('user/',include('apps.user.urls')),
path('course/',include('apps.course.urls')),
path('goods/',include('apps.goods.urls')),
]
#註冊子路由
from user import views
from user.views import *
from rest_framework.routers import DefaultRouter,SimpleRouter
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns={
path('login/',obtain_jwt_token),
path("jwtuser/",RegisterView.as_view()),
path("userinfo/",UserListView.as_view())
}
重寫user表
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) user/model.py
設定序列化器
from .models import *
from rest_framework import serializers
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from rest_framework_jwt.settings import api_settings
from rest_framework import serializers
from user.models import User
from django.contrib.auth.hashers import make_password
from utils.MyModelVIew import create_token
class UserSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
email=serializers.CharField()
phone = serializers.CharField()
token = serializers.CharField(read_only=True)
def create(self,data):
user = User.objects.create(**data)
password=make_password(data.get("password"))
user.password=password
user.save()
token=create_token(user)
user.token = token
return user
class UserInfoSer(serializers.ModelSerializer):
class Meta:
model=User
fields="__all__"
'''再寫views'''
from django.http import JsonResponse
from django.shortcuts import render
from rest_framework.views import View,APIView
from rest_framework.response import Response
from django.db.models import Q
from django.contrib.auth.backends import ModelBackend #驗證基類
class UsernameMobileAuthBackend(ModelBackend):
#重寫驗證方式
def authenticate(self, request, username=None, password=None, MyUser=None, **kwargs):
user = User.objects.get(Q(username=username) | Q(phone=username))
if user is not None and user.check_password(password):
return user
def Login_return(token,user=None,request=None): ''' login介面返回引數,與settings 對應 :param token: :param user: :param request: :return: ''' return { 'token':token, 'user':user.username, 'user.id':user.id } 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 user.serliazers import UserSerializer from .models import * from user.serliazers import UserInfoSer # 使用者註冊 class RegisterView(APIView): def post(self, request, *args, **kwargs): data=request.data if not all(["username","phone","email","password"]): return Response({"code":4003,"msg":"chanshubuwanzheng"},status=200) try: user=UserSerializer(data=data) user.is_valid() user.save() res_data={ "code":0, "msg":"sussesful", "data":user.data } return Response(res_data) except Exception as e: res_data={ "code": 400, "msg": "Defect", } return Response(res_data) # serializer = UserSerializer(data=request.data) # if serializer.is_valid(): # serializer.save() # return Response(serializer.data, status=201) # return Response(serializer.errors, status=400) # 測試必須攜帶token才能訪問介面 class UserListView(APIView): permission_classes = [IsAuthenticated] # 介面中加許可權 authentication_classes = [JSONWebTokenAuthentication] def get(self,request, *args, **kwargs): user=User.objects.all() ser=UserInfoSer(user,many=True) res_data={ "code":200, "msg":"susseful", "data":ser.data } return Response(res_data)
全域性配置介面需要jwt驗證
#jwt設定 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), #配置全部介面需要驗證才能發訪問,驗證方式為登陸使用者 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), } setting.py
區域性介面解除jwt驗證要求
class RegisterView(APIView): # 在此介面中允許所有使用者訪問,去除jwt的驗證要求 permission_classes = [AllowAny] 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) user/views.py
自定義驗證方式:要求手機或者郵箱也可作為登陸手段
AUTHENTICATION_BACKENDS = [ 'userapp.views.UsernameMobileAuthBackend', ]
views
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 views.py