首页 > 其他 > 详细

drf-认证

时间:2020-07-10 09:41:17      阅读:85      评论:0      收藏:0      [点我收藏+]

1 认证Authentication

认证的写法

# 认证的实现
    1 写一个类,继承BaseAuthentication,重写authenticate,认证的逻辑写在里面,认证通过,返回两个值,一个值最终给了Requet对象的user,认证失败,抛异常:APIException或者AuthenticationFailed
    2 全局使用,局部使用

1.1 自定义认证方案

1.1.1 编写models

models.py

from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish = models.CharField(max_length=32)

# ===========================认证用到的============================
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):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to=User, on_delete=models.CASCADE)   # on_delete=models.CASCADE级联删除

1.1.2 新建认证类

app01/app_auth.py

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)

1.1.3 编写视图

views.py

from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from app01.models import Book
from app01.serializers import BookSerializer
from rest_framework.decorators import action  # 装饰器
from rest_framework.response import Response
# ===============认证相关===========================
from app01.app_atuh import MyAuthentication
from app01 import models
import uuid

# Create your views here.
class BookViewSet(ModelViewSet):
    authentication_classes = [MyAuthentication, ]     # 局部使用认证
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    @action(methods=[GET, POST], detail=True)
    def get_1(self, request, pk):
        print(pk)
        book = self.get_queryset()[:1]  # 从0开始截取一条
        ser = self.get_serializer(book, many=True)
        return Response(ser.data)

class LoginView(APIView):
    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")
        user = models.User.objects.filter(username=username, password=password).first()
        if user:
            # 登录成功,生成随机字符串
            token = uuid.uuid4()
            # 存到UserToken表中
            # models.UserToken.objects.create(token=u_str, user=user)   # 用它每次登录都会记录一条,不好,
            # update_or_create有就更新,没有就新增
            models.UserToken.objects.update_or_create(defaults={token: token}, user=user)
            return Response({status: 200, msg: 登录成功, token: token})
        else:
            return Response({status: 101, msg: 用户名或密码错误})

1.1.4 路由

urls.py

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path(admin/, admin.site.urls),
    path(login/, views.LoginView.as_view()),
]


from rest_framework import routers
router = routers.SimpleRouter()
router.register(books, views.BookViewSet)  # 不要加斜杠了

urlpatterns += router.urls

1.1.5 全局使用(在项目settings.py配置文件中配置)

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}

1.1.6 局部使用

#局部使用,只需要在视图类里加入:
authentication_classes = [TokenAuth, ]

 

drf-认证

原文:https://www.cnblogs.com/baicai37/p/13277207.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!