1、drf 的用户认证组件
(1)models
from django.db import models
# Create your models here.
class User(models.Model):
username=models.CharField(max_length=64)
password=models.CharField(max_length=64)
user_type=models.IntegerField(choices=((1,'超级用户'),
(2,'普通用户'),
(3,'的用户')
))
class UserToken(models.Model):
token=models.CharField(max_length=64)
user=models.OneToOneField(to='user',on_delete=models.CASCADE)
(2)urls
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('test/',views.test.as_view()),
]
(3)MyAuthentication
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
# 认证逻辑 如果认证通过 返回两个值
# 如果认证失败 AuthenticationFailed异常
token=request.GET.get('token')
if token:
user_token=UserToken.objects.filter(token=token).first()
# 认证通过
if user_token:
return user_token.user,token
else:
raise AuthenticationFailed('认证失败')
else:
raise AuthenticationFailed('请求地址中需要携带token')
(4) views
from django.shortcuts import render
import uuid
from app01.models import User
from app01 import models
# Create your views here.
from rest_framework.views import APIView
from app01.app_auth import MyAuthentication
from rest_framework.response import Response
class test(APIView):
def post(self,request):
username=request.data.get('username')
password=request.data.get('password')
user=User.objects.filter(username=username,password=password).first()
if user:
token = uuid.uuid4()
models.UserToken.objects.update_or_create(defaults={'token':token},user=user)
print('当前登录的用户',request.user.username)
return Response({'status':100,'msg':'登录成功','token':token})
else:
return Response({'status':101,'msg':'用户名或密码错误'})
def get(self,request):
return Response({'status':100})
(5)局部配置认证
authentication_classes = [MyAuthentication]
(6)全局配置认证
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}