Rest Framework: IV. authentication component

I. create LoginAuth class to complete the authentication process

urls.py

url(r'^login/', views.Login.as_view()),
url(r'^books/', views.Books.as_view()),

models.py

from django.db import models

# Create your models here.
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    #Write choice
    user_choice=((0,'Ordinary users'),(1,'Member'),(2,'Super user'))
    #Specify a choice to quickly retrieve text through numbers
    user_type=models.IntegerField(choices=user_choice,default=0)
    pwd = models.CharField(max_length=32)

class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to=UserInfo)

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

    def test(self):
        return self.email

Migrating databases

python3 manage makemigrations
python3 manage migrate


app01/MySerializer.py

from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields='__all__'

views.py

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from app01 import models
import hashlib
import time
from django.core.exceptions import ObjectDoesNotExist
from app01 import MySerializer


# Create your views here.

def get_token(name):
    #Generate an md5 object
    md5 = hashlib.md5()
    #Add value to, must be in bytes format
    #time.time() generates a timestamp type, converts it to a string, and encode s it to bytes
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()


class Login(APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': 'Login successfully'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        try:
            user = models.UserInfo.objects.get(name=name, pwd=pwd)
            #Pass the verification, log in successfully, and generate a random string (identity) token
            token = get_token(name)
            #Save to database
            #Update or create
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        except ObjectDoesNotExist as e:
            response['status'] = 101
            response['msg'] = 'Wrong user name or password'
        except Exception as e:
            response['status'] = 102
            #response['msg '] =' unknown error '
            response['msg'] = str(e)
        return JsonResponse(response, safe=False)


from rest_framework import exceptions


class LoginAuth():
    #Function name must be called this name, receive must have two parameters, and the second parameter is request object
    def authenticate(self, request):
        #Take the token from the request pair (or from other places)
        token = request.query_params.get('token')
        #Query in database
        ret = models.UserToken.objects.filter(token=token)
        if ret:
            #It can be found, indicating that the authentication is passed, and the return is empty
            return None
        #Otherwise, an exception will be reported
        raise exceptions.APIException('Authentication failed')


from rest_framework.request import Request


# class Books(APIView):
#     #Types in the list cannot be parenthesized
#     authentication_classes = [LoginAuth, ]
#
#     def get(self, request, *args, **kwargs):
#response = {'status': 100,' msg ': query succeeded'}
#         #You must log in to get data
#         #Take the token, take the database for verification, and log in or not
#         token = request.query_params.get('token')
#         ret = models.UserToken.objects.filter(token=token)
#         if ret:
#             #Authentication passed, login user
#             ret = models.Book.objects.all()
#             book_ser = MySerializer.BookSerializer(ret, many=True)
#             response['data'] = book_ser.data
#         else:
#             response['status'] = 101
#response['msg '] =' authentication failed '
#         return JsonResponse(response, safe=False)

#Same function as the Books class above, but more concise than the one above.
class Books(APIView):
    #Types in the list cannot be parenthesized
    authentication_classes = [LoginAuth, ]

    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': 'query was successful'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)

Add data test to database:

Using Postman testing:

Function: log in to view the details of the book

Log in to the service using the user name and password in the database:

Use token login to verify the details of the query book

If the token verification is not successful, it will return:

II. Global and local use of authentication components

urls.py, models.py, invariant

Local use:

views.py

from app01.MyAuth import LoginAuth
class Books(APIView):
    #Types in the list cannot be parenthesized
    #Local use of certified components
    authentication_classes = [LoginAuth, ]
    #Authentication component, local disable authentication \ classes = []
    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': 'query was successful'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)

app01/MyAuth.py

from rest_framework import exceptions
from app01 import models
#Using dnf authentication to write a class
class LoginAuth():
    #Function name must be called this name, receive must have two parameters, and the second parameter is request object
    def authenticate(self, request):
        #Take the token from the request pair (or from other places)
        token = request.query_params.get('token')
        #Query in database
        ret = models.UserToken.objects.filter(token=token)
        if ret:
            #It can be found, indicating that the authentication is passed, and the return is empty
            return None
        #Otherwise, an exception will be reported
        raise exceptions.APIException('Authentication failed')

-Global use
- configure in setting:

REST_FRAMEWORK={
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
}

-Locally disabled, in views.py:

Authentication component, local disable authentication ﹣ classes = []

III. establishment of authority





Tags: Python Database Django

Posted on Tue, 03 Dec 2019 11:17:28 -0500 by cornercuttinjoe