DRF之认证

登录功能

  models.py

from django.db import models


# Create your models here.
class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    user_type = models.IntegerField(choices=((1, '超级管理员'), (2, '普通管理员',), (3, '普通用户')))


class UserToken(models.Model):
    user = models.OneToOneField(to=User, on_delete=models.CASCADE)
    token = models.CharField(max_length=32)
View Code

  views.py

from django.shortcuts import render

# Create your views here.
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from .models import User, UserToken
from rest_framework.response import Response
import uuid


class UserView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()
        if user:
            # 登录成功--生成一个随机字符串--存在token表中(如果之前有记录,更新,如果没有新增)
            token = str(uuid.uuid4())
            UserToken.objects.update_or_create(user=user, defaults={'token': token})  # 如果存在就更新,如果不存在就新增
            return Response({'code': 100, 'msg': '登陆成功', 'token': token})
        else:
            return Response({'code': 101, 'msg': '用户名或者密码错误'})
View Code

  urls.py

from django.contrib import admin
from django.urls import path,include
from app01 import views
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('user', views.UserView, 'user')
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
]
View Code

认证类

  认证类:用来校验用户是否登录,如果登录了,继续往下走,如果没有登陆,直接返回

  编写步骤

    第一步

    写一个类,继承BaseAuthentication,重写authenticate,在方法中做校验,校验是否登录,返回两个值,没有登录抛异常

    第二步

    全局配置,在配置文件中

      REST_FRAMEWORK={
      "DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.LoginAuth",]
          }

    局部配置,在视图类中

      class UserView(ViewSet):
        authentication_classes = [LoginAuth]

    局部禁用

       class UserView(ViewSet):
            authentication_classes = [] 

  具体代码

    auth.py(自己写的)

from rest_framework.authentication import BaseAuthentication
from .models import UserToken
from rest_framework.exceptions import AuthenticationFailed


class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get('token')
        user_token = UserToken.objects.filter(token=token).first()
        if user_token:
            # 登录了
            # 返回两个值,第一个当前登录用户,第二个token返回
            return user_token.user, token
        else:
            # 抛出认证失败的异常
            raise AuthenticationFailed('你没有登录')
View Code

    models.py

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
    author = models.CharField(max_length=32)
View Code

    views.py

from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
from .auth import LoginAuth


class BookView(ModelViewSet):
    # authentication_classes = [LoginAuth, ]
    queryset = Book.objects.all()
    serializer_class = BookSerializer
View Code

 

 认证类中返回的两个变量

  返回的第一个,给了request.user,就是当前登录用户

  返回的第二个,给了request.auth,就是token串

 

posted @ 2022-04-08 19:07  那就凑个整吧  阅读(35)  评论(0编辑  收藏  举报