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
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', ), }
~>.<~