程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Note: overview of user-defined use process of Django rest framework apiview certification class

編輯:Python

Validation classes can be used locally ( In a separate views Introduction in ), It can also be used globally ( stay settings Middle configuration )

Usage flow 1: First, define a user-defined authentication class ( such as MyAuth), Then rewrite authenticate() Method , Put the logic that needs authentication into this function and write , Then notice that the return value is a tuple . Then when you need to use this validation class view Inside the view use authentication_classes = [MyAuth,] Wrap the list , That's all right. .



Usage flow 2: For the above use, write the list of authentication classes in the required view . If there are too many views , Write more … So you can also put settings.py In file , The following format :

TIPS: If the authentication class is set in the global , It means that all views will pass this authentication class , So if some views need this authentication class , You can only set it separately in this view authentication_classes = [] This list is empty , Means not to deal with .

authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
REST_FRAMEWORK = {

# Authentication classes used globally 
'DEFAULT_AUTHENTICATION_CLASSES':['api.utils.auth.FirstAuthenticate'] # Note this format , there DEFAULT_AUTHENTICATION_CLASSES yes restframework Configure the specified , The following list is the certified classes . The path of the authentication class is written inside 
# The following two sentences are the settings of anonymous users :
'UNAUTHENTICATED_USER':None, # anonymous , be request.user = None
'UNAUTHENTICATED_TOKEN':None # anonymous , be request.token = None
}

Verify whether the login is successful

Custom validation class , Inherit BaseAuthentication, The advantage of inheriting this class here is that we only need to write one authenticate() That's all right. , The other is because of inheritance , The parent class already exists , You don't have to rewrite it , as follows :

class MyAuthenticate1(BaseAuthentication):
def authenticate(self, request):
# Verify what the user brought token
token = request._request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
print(token)
print(token_obj)
if not token_obj:
raise exceptions.AuthenticationFailed(' User authentication failed ')
return (token_obj.user, token_obj) # Must return a tuple , restframeworkd Two fields are assigned to request, A total of subsequent use .
def authenticate_header(self, request):
pass

Summary process

First step : Create an authentication class : Inherited from BaseAuthentication Realization authenticate Method

  • Return value There are three kinds of :
    • None, I don't deal with it , Leave it to the next authentication class .
    • Failure , raise exceptions.AuthenticationFailed(‘ User authentication failed ’)
    • success Will return a binary , ( Elements 1, Elements 2) They will be assigned to request.user, request.auth

Two application scopes of certification :

  • A kind of Local use , Reference only in specific attempts
  • Global use , stay settings Written in

The source code is as follows :

The directory structure of the project is shown in the figure below :

1, models.py as follows :

from django.db import models
class UserInfo(models.Model):
user_type_choices = (
(1, ' Ordinary users '),
(2, 'VIP'),
(3, 'SVIP')
)
user_type = models.IntegerField(choices=user_type_choices)
username = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=64)
class UserToken(models.Model):
user = models.OneToOneField(to=UserInfo, on_delete=models.CASCADE)
token = models.CharField(max_length=64)

2, urls.py as follows :

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from api import views
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/v1/auth/$', views.AuthView.as_view()),
url(r'^api/v1/order/$', views.OrderView.as_view())
]

3, views.py

from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication, BaseAuthentication
from rest_framework import exceptions
from api import models
from api.utils.auth import FirstAuthenticate
# This md5 Function takes user and time to generate md5 The random value , Used to generate token
def md5(user):
import hashlib
import time
ctime = str(time.time())
m = hashlib.md5(bytes(user, encoding='utf-8'))
m.update(bytes(ctime, encoding='utf-8'))
return m.hexdigest()
class AuthView(APIView):
''' For user login Here you can get the user name and password sent by the front desk , Then go to the database to verify , At the same time, we also generated token, Then it returns to the user token, It is used for sending requests after users , It has to be Take this with you token Request . '''
authentication_classes = [] # Here, because the validation class is set in the global , So leave this list blank , So that this view can not be verified globally , Direct execution .
def get(self, request, *args, **kwargs):
return HttpResponse('hello workd')
def post(self, request, *args, **kwargs):
ret = {
'code':1000, 'msg':None}
try:
user = request._request.POST.get('username')
password = request._request.POST.get('password')
obj = models.UserInfo.objects.filter(username=user, password=password).first()
if not obj:
ret['code'] = 1001
ret['msg'] = ' Wrong username or password '
# Not logged in user created token, Use the definition of md5() Function to generate token
token = md5(user)
# Save the gold database , Update if you have , Create without , Because you can only use the latest token, So you need to update .
models.UserToken.objects.update_or_create(user=obj, defaults={
'token':token})
# You need to return to the user token
ret['token'] = token
except Exception as e:
ret['code']=1002
ret['msg']=' Request exception '
return JsonResponse(ret)
# Define a dictionary of orders , Simulate an order with a dictionary 
ORDER_DICT= {

1: {

'name': ' purchasing power parity ',
'age': 12,
'gender': ' male ',
'content': '...'
},
2: {

'name': ' Fake data ',
'age': 12,
'gender': ' male ',
'content': '...'
},
}
# Custom validation class , No inheritance 
class MyAuthenticate(object):
def authenticate(self, request):
# Verify what the user brought token
token = request._request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
print(token)
print(token_obj)
if not token_obj:
raise exceptions.AuthenticationFailed(' User authentication failed ')
return (token_obj.user, token_obj) # Must return a tuple , restframeworkd Two fields are assigned to request, A total of subsequent use .
def authenticate_header(self, request):
pass
# Custom validation class , Inherit BaseAuthentication, The advantage of inheriting this class here is that we only need to write one authenticate() That's all right. , The other is because of inheritance , The parent class already exists ,
# You don't have to rewrite it .
class MyAuthenticate1(BaseAuthentication):
def authenticate(self, request):
# Verify what the user brought token
token = request._request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
print(token)
print(token_obj)
if not token_obj:
raise exceptions.AuthenticationFailed(' User authentication failed ')
return (token_obj.user, token_obj) # Must return a tuple , restframeworkd Two fields are assigned to request, A total of subsequent use .
def authenticate_header(self, request):
pass
class OrderView(APIView):
authentication_classes = [FirstAuthenticate, MyAuthenticate,] # use restframework The authentication class of , Format : First write an authentication class , Then it can be used here , The logic code is implemented in the above custom authentication class .
def get(self, request, *args, **kwargs):
print(request.user)
print(request.auth)
ret = {
'code':1000, 'msg':None, 'data':None} # Used to mark whether the request is successful And data 
# Mark the user to log in to see the data here , Otherwise, you won't see the data 
# Here we use the above token,, Because only login , Generation token, The user has logged in , Otherwise no token, It means that the user has not logged in 
# The authentication method here is more traditional , Not used restframework The certification of the class , If there are many views , You need to write this authentication function in the middle of each view ,
# We can customize a validation class , Then rewrite authenticate() Method , Write the statement to verify login , Then it is necessary to call here . Once and for all 
# token = request._request.GET.get('token')
# if not token:
# return HttpResponse(' The user is not logged in , Can't view ')
try:
ret['data'] = ORDER_DICT
except Exception as e:
pass
return JsonResponse(ret)

4, Custom validation class route : api/utils/auth.py

from rest_framework import exceptions
from api import models
# Custom validation class 
class FirstAuthenticate(object):
def authenticate(self, request):
# Verify what the user brought token
token = request._request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
print(token)
print(token_obj)
if not token_obj:
raise exceptions.AuthenticationFailed(' User authentication failed ')
return (token_obj.user, token_obj) # Must return a tuple , restframeworkd Two fields are assigned to request, A total of subsequent use .
def authenticate_header(self, request):
pass

5, settings.py The documents are as follows :

""" Django settings for auth2 project. Generated by 'django-admin startproject' using Django 3.0.5. For more information on this file, see https://docs.djangoproject.com/en/3.0/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/3.0/ref/settings/ """
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'p)rim!kr+qd(&x$b&p9!%6nwelaw%x)^y6optft1([email protected]'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'auth2.urls'
TEMPLATES = [
{

'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join (BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {

'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'auth2.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{

'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{

'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{

'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{

'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
REST_FRAMEWORK = {

'DEFAULT_AUTHENTICATION_CLASSES':['api.utils.auth.FirstAuthenticate',], # Note this format , there DEFAULT_AUTHENTICATION_CLASSES yes restframework Configure the specified , The following list is the certified classes . The path of the authentication class is written inside 
# The following two sentences are the settings of anonymous users :
'UNAUTHENTICATED_USER':None, # anonymous , be request.user = None
'UNAUTHENTICATED_TOKEN':None # anonymous , be request.token = None
}

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved