一, 认证组件的作用
在一个程序中有一些功能是需要登录才能使用的, 原生 Django 中的 auth 组件可以用来解决这个认证问题, drf 框架中也有对应的认证组件来解决这个问题.
models.py
- from django.db import models
- # Create your models here.
- class User(models.Model):
- name = models.CharField(max_length=16)
- pwd = models.CharField(max_length=16)
- class TokenUser(models.Model):
- token = models.CharField(max_length=256)
- user = models.OneToOneField(to='User',null=True,on_delete=models.SET_NULL,db_constraint=False)
- class Book(models.Model):
- name = models.CharField(max_length=16)
- price = models.IntegerField()
- publish_date = models.DateField()
myserializer.py 序列化
- from rest_framework import serializers
- from app01 import models
- class BookSerializer(serializers.ModelSerializer):
- class Meta:
- model = models.Book
- fields = '__all__'
- def validate(self, attrs):
- return attrs
二, 自定义版登录验证组件
urls.py
- """blog_test URL Configuration
- The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/1.11/topics/http/urls/
- Examples:
- Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
- Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
- Including another URLconf
- 1. Import the include() function: from django.conf.urls import url, include
- 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
- """
- from django.conf.urls import url
- from django.contrib import admin
- from app01.views import BooksView, BookView,Login
- urlpatterns = [
- url(r'^admin/', admin.site.urls),
- url(r'^Login/$', Login.as_view()),
- url(r'^Books/$', BooksView.as_view()),
- url(r'^Books/(?P<pk>\d+)/$', BookView.as_view()),
- ]
myauth.py 自定义验证类
- from rest_framework.authentication import BaseAuthentication
- from app01.models import TokenUser
- from rest_framework.exceptions import AuthenticationFailed
- class MyAuthentication():
- #验证过程
- def authenticate(self, request):
- token = request.GET.get('token')
- token_user = TokenUser.objects.filter(token=token).first()
- if token_user:
- return token_user.user,token
- else:
- raise AuthenticationFailed('你还未登录, 请先登录')
- def authenticate_header(self, request):
- pass
views.py 视图类
- from django.shortcuts import render
- from rest_framework.response import Response
- # Create your views here.
- from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
- from app01 import models
- from app01.myserializer import BookSerializer
- from rest_framework.views import APIView
- from app01.myAuth import MyAuthentication
- class BooksView(ListCreateAPIView):
- authentication_classes = [MyAuthentication] #加上验证的类, 如果有多个, 会从做到右依次验证
- queryset = models.Book.objects.all()
- serializer_class = BookSerializer
- class BookView(RetrieveUpdateDestroyAPIView):
- authentication_classes = [MyAuthentication]
- queryset = models.Book.objects.all()
- serializer_class = BookSerializer
- import uuid
- # 登录
- class Login(APIView):
- def post(self,request):
- name = request.data.get('name')
- pwd = request.data.get('pwd')
- user = models.User.objects.filter(name=name,pwd=pwd).first()
- if user:
- token = uuid.uuid4()
- models.TokenUser.objects.update_or_create(user=user,defaults={"token":token})
- response = {"status":100,"message":"登录成功"}
- else:
- response = {"status": 200, "message": "登录失败"}
- return Response(response)
结果: 登录后会在数据库中生成一个 token, 用 get 请求将其发送, 观察各个请求的结果.
结果 1:
结果 2:
三, 继承 BaseAuthentication 的类的登录验证组件
myauth.py
- from rest_framework.authentication import BaseAuthentication
- from app01.models import TokenUser
- from rest_framework.exceptions import AuthenticationFailed
- class MyAuthentication():
- #验证过程
- def authenticate(self, request):
- token = request.GET.get('token')
- token_user = TokenUser.objects.filter(token=token).first()
- if token_user:
- return token_user.user,token
- else:
- raise AuthenticationFailed('你还未登录, 请先登录')
其他代码一致
四, 认证组件的使用方式
1. 局部使用: 在需要使用登录验证的视图类中写上变量 authentication_classes= [ 验证类名,]
2. 全局使用: 在 settings.py 配置文件中, 加入 REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES':'验证类的具体位置例如 (app01.myauth.MyAuthenyicatin)'}
3. 全局使用, 局部禁用: 在全局使用的基础上, 在不需要验证的视图类中, 将变量 authentication_classes 改为 [ ] 即 authentication_classes = [ ]
五, 认证组件源代码分析
来源: http://www.bubuko.com/infodetail-3003248.html