DRF Django REST framework of authentication component (E)

introduction

A long time ago, a Web site only as a browse server resources (data) tools and other resources, what little annoying things like user interactions need to be addressed, therefore, the development of Web sites that do not care what people at what time access to what resources do not need to record any data, the client has requested that I return data that is simple and convenient, every http request is new, disconnected immediately after the response.

Today, the Internet world has undergone tremendous changes, users only need to communicate with other users, need to keep server interaction, whether it is the forum category, store type, social class, portal type or other types of Web sites, we are attaches great importance to user interaction, only the interaction with the user, in order to further retain customers, only to retain the user in order to know the needs of the user, the user needs to know, will generate business opportunities, with the user, is equivalent with the flow, to be able to fool ... ... it is the amount of money to financial, corporate funds to continue with the development, visibility, user interaction is very important, and can even be said to be crucial to a basic function.

On the issue of user interaction, you have to talk about knowledge, certification, permissions, and frequency we want to learn today. First we look at certification.

Certified Components

Use token

Most people know this cookie and session two ways to store user information, two different ways is a cookie stored in the client browser, and session stored in the server, they have advantages and disadvantages, and together use, It can be important sensitive information is stored in the session, but can be stored in a cookie less sensitive data.

The token is called a token. cookie, session token and have their application scenarios, not who is good and who's bad, but Web application development data interface classes, currently with the token, or more.

Substantially token authentication step is such that:

  • User login, password server to obtain a user name, query the user table, and the first log in. If the user exists (or token expired), generates token, otherwise it returns an error message
  • If this is not the first time you log in, and the token has not expired, update token value

Defined  url 

from django.urls import path, re_path

from DrfOne import views

urlpatterns = [

    path("books/", views.BookView.as_view({
        "get": "list",
        "post": "create",
    })),
    re_path('books/(?P<pk>\d+)/', views.BookView.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    })),

    # 登陆
    path('login/', views.LoginView.as_view()),
]

Create two  Model  , as follows:

from django.db import models

class UserInfo(models.Model): username = models.CharField("姓名", max_length=32) password = models.CharField("密码", max_length=32) Age = models.IntegerField ( " Age " ) gender = models.SmallIntegerField("性别", choices=((1, ""), (2, "")), default=1) user_type_entry = ((. 1, " normal users " ), (2, " the VIP " ), (. 3, " SVIP " )) user_type = models.SmallIntegerField ( " user level " , choices = user_type_entry) def __str__(self): return self.username class UserToken(models.Model): user = models.ForeignKey(to="UserInfo", on_delete=models.CASCADE) token = models.CharField(max_length=128)

 post  method for an interface, the view classes are as follows:

from django.http import JsonResponse

from rest_framework.views import APIView

from DrfTwo.models import UserInfo, UserToken


class the LoginView (APIView):
     DEF POST (Self, Request):
         # define return information 
        RET = dict ()
         the try :
             # definition requires information 
            Fields = { " username " , " password " }
             # defines a user information dictionary 
            USER_INFO = dict ()
             # determine whether the fields are a subset of request.data 
            iF fields.issubset (the sET (request.data.keys ())):
                 for Key in fields:
                    user_info[key] = request.data.get(key)

            user_instance = UserInfo.objects.filter (** user_info) .first ()
             # User authentication 
            IF user_instance:
                 # Custom generate_token () method to get token value, behind 
                the access_token = generate_token ()
                 # successful login, create a token, token presence update token, defaults to update 
                UserToken.objects.update_or_create (= User user_instance, Defaults = {
                     " token " : the access_token
                })
                ret["status_code"] = 200
                ret["status_message"] = "登录成功"
                ret["access_token"] = access_token
                ret["user_role"] = user_instance.get_user_type_display()

            else:
                RET [ " status_code " ] = 201 
                RET [ " STATUS_MESSAGE " ] = " Login failed, user name or password is incorrect " 
        the except Exception AS E:
            ret["status_code"] = 202
            ret["status_message"] = str(e)


        return JsonResponse(ret)

Write a simple method for obtaining generating a random string token values:

import uuid


def generate_token():
    random_str = str(uuid.uuid4()).replace("-", "")
    return random_str

The above is a simple way to generate token, of course, in a production environment is not so simple, there are about token associated with the library, and then after a few configuration data, you can create several user's token information POSTMAN tool.

 

Next, how to achieve access to authorized users have logged in success? That is, only logged in users (there are token value) to access specific data, the authentication component played DRF

The use of certified components

First, a new class certification, after authentication logic in this class which contains:

# 1. Define authentication class 
class USERAUTH (Object):
     # authentication logic 
    DEF the authenticate (Self, Request):
        user_token = request.GET.get('token')

        token_object = UserToken.objects.filter(token=user_token).first()
        if token_object:
            return token_object.user.username, token_object.token
        else:
            raise APIException("认证失败")

Implementation looks very simple, to the  token  table inside view  token  if there is, then based on this information, the corresponding information can return, then, the need to authenticate data interface which can be registered by a certification class can access:

from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import APIException

from DrfOne.models import Book, UserToken
from DrfOne.drf_serializers import BookSerializer


# 1. Define authentication class 
class USERAUTH (Object):
     # authentication logic 
    DEF the authenticate (Self, Request):
        user_token = request.GET.get('token')

        token_object = UserToken.objects.filter(token=user_token).first()
        if token_object:
            return token_object.user.username, token_object.token
        else:
            raise APIException("认证失败")


class BookView (ModelViewSet):
     # 2. Specify the authentication type, fixed wording 
    authentication_classes = [USERAUTH]
     # acquire a data source, the fixed wording 
    QuerySet = Book.objects.all ()
     # sequence of categories, the fixed wording 
    serializer_class = BookSerializer

Sequence class  BookSerializer 

from rest_framework import serializers

from DrfOne import models


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = "__all__"

        extra_kwargs = {
            # 仅写
            "publish": {'write_only': True},
            "authors": {'write_only': True},
        }

    publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name")
    publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
    author_name = serializers.SerializerMethodField()

    def get_author_name(self, book_obj):
        author_list = List ()
         for author in book_obj.authors.all ():
             # Note that the list add fields, author.name not the author 
            author_list.append (author.name)
         return author_list
Class BookSerializer

Multiple certification class

Note that, if the need to return any data, a return to the last authentication class, because if the front return, the source  self._authentication ()  method returns the value will be determined, if not empty, certification procedure is aborted, implementation of multiple certification classes are as follows:

# 1. Define authentication class 
class USERAUTH (Object):
     # authentication logic 
    DEF the authenticate (Self, Request):
        user_token = request.GET.get('token')

        token_object = UserToken.objects.filter(token=user_token).first()
        if token_object:
            return token_object.user.username, token_object.token
        else:
            raise APIException("认证失败")


class UserAuthTwo (Object):
     DEF the authenticate (Self, Request):
         The raise ApiException ( " It's that simple! " )


class BookView (ModelViewSet):
     # 2. Specify the authentication type, fixed wording 
    authentication_classes = [USERAUTH, UserAuthTwo]
     # acquire a data source, the fixed wording 
    QuerySet = models.Book.objects.all ()
     # sequence of categories, the fixed wording 
    serializer_class = BookSerializer

Global Certification

If you want all the data interfaces need to be verified how to do? Quite simply, if certification class he did not  authentication_classes  , it will be the  settings  in the find, through this mechanism, we can write the class certification to the  settings  file you can achieve global certification:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'authenticator.utils.authentication.UserAuth',
        'authenticator.utils.authentication.UserAuth2',
    ),
}

~>.<~

Guess you like

Origin www.cnblogs.com/pungchur/p/12028381.html