DRF Django REST framework 之 认证组件(五)

引言

很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任何数据,有客户端请求,我即返回数据,简单方便,每一个http请求都是新的,响应之后立即断开连接。

而如今,互联网的世界发生了翻天覆地的变化,用户不仅仅需要跟其他用户沟通交流,还需要跟服务器交互,不管是论坛类、商城类、社交类、门户类还是其他各类Web站点,大家都非常重视用户交互,只有跟用户交互了,才能进一步留住用户,只有留住了用户,才能知道用户需求,知道了用户需求,才会产生商机,有了用户,就等于有了流量,才能够骗到…额…是融到钱,有了资金企业才能继续发展,可见,用户交互是非常重要的,甚至可以说是至关重要的一个基础功能。

而谈到用户交互,则必须要谈到我们今天所要学习的知识点,认证、权限和频率。首先我们来看看认证。

认证组件

使用token

大部分人都知道cookie和session这两种方式可以保存用户信息,这两种方式不同的是cookie保存在客户端浏览器中,而session保存在服务器中,他们各有优缺点,配合起来使用,可将重要的敏感的信息存储在session中,而在cookie中可以存储不太敏感的数据。

而token称之为令牌。cookie、session和token都有其应用场景,没有谁好谁坏,不过开发数据接口类的Web应用,目前用token还是比较多的。

token认证的大致步骤是这样的:

  • 用户登录,服务器端获取用户名密码,查询用户表,如果存在该用户且第一次登录(或者token过期),生成token,否则返回错误信息
  • 如果不是第一次登录,且token未过期,更新token值

定义 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()),
]

创建两个 model ,如下所示:

from django.db import models

class UserInfo(models.Model):
    username = models.CharField("姓名", max_length=32)
    password = models.CharField("密码", max_length=32)
    age = models.IntegerField("年龄")
    gender = models.SmallIntegerField("性别", choices=((1, "男"), (2, "女")), default=1)
    user_type_entry = ((1, "普通用户"), (2, "VIP"), (3, "SVIP"))
    user_type = models.SmallIntegerField("用户级别", 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 方法接口,视图类如下所示:

from django.http import JsonResponse

from rest_framework.views import APIView

from DrfTwo.models import UserInfo, UserToken

class LoginView(APIView):
    def post(self, request):
        # 定义返回信息
        ret = dict()
        try:
            # 定义需要的信息
            fields = {"username", "password"}
            # 定义一个用户信息字典
            user_info = dict()
            # 判断fields是否是request.data的子集
            if fields.issubset(set(request.data.keys())):
                for key in fields:
                    user_info[key] = request.data.get(key)

            user_instance = UserInfo.objects.filter(**user_info).first()
            # 用户验证
            if user_instance:
                # 自定义generate_token()方法,获取token值,在后面
                access_token = generate_token()
                # 用户登陆成功,创建token,token存在更新token, defaults为更新内容
                UserToken.objects.update_or_create(user=user_instance, defaults={
                    "token": 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"] = "登录失败,用户名或密码错误"
        except Exception as e:
            ret["status_code"] = 202
            ret["status_message"] = str(e)

        return JsonResponse(ret)

简单写了个获取随机字符串的方法用来生成token值:

import uuid

def generate_token():
    random_str = str(uuid.uuid4()).replace("-", "")
    return random_str

以上就是token的简单生成方式,当然,在生产环境中不会如此简单,关于token也有相关的库,然后在构造几条数据之后,可以通过POSTMAN工具来创建几个用户的token信息。

接下来,如何对已经登录成功的用户实现访问授权呢?也就是说,只有登录过的用户(有token值)才能访问特定的数据,该DRF的认证组件出场了

认证组件的使用

首先,新建一个认证类,之后的认证逻辑就包含在这个类里面:

# 1.定义认证类
class UserAuth(object):
    # 认证逻辑
    def 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("认证失败")

实现方式看上去非常简单,到 token 表里面查看 token 是否存在,然后根据这个信息,返回对应信息即可,然后,在需要认证通过才能访问的数据接口里面注册认证类即可:

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.定义认证类
class UserAuth(object):
    # 认证逻辑
    def 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.指定认证类,固定写法
    authentication_classes = [UserAuth]
    # 获取数据源, 固定写法
    queryset = Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

序列类 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():
            # 注意列表添加字段,author.name而不是author
            author_list.append(author.name)
        return author_list

类BookSerializer

多个认证类

需要注意的是,如果需要返回什么数据,请在最后一个认证类中返回,因为如果在前面返回,在源码的 self._authentication() 方法中会对返回值进行判断,如果不为空,认证的过程就会中止,多个认证类的实现方式如下:

# 1.定义认证类
class UserAuth(object):
    # 认证逻辑
    def 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 authenticate(self, request):
        raise APIException("就是这么简单!")

class BookView(ModelViewSet):
    # 2.指定认证类,固定写法
    authentication_classes = [UserAuth, UserAuthTwo]
    # 获取数据源, 固定写法
    queryset = models.Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

全局认证

如果希望所有的数据接口都需要认证怎么办?很简单,如果认证类自己没有 authentication_classes ,就会到 settings 中去找,通过这个机制,我们可以将认证类写入到 settings 文件中即可实现全局认证:

REST_FRAMEWORK = {
    ‘DEFAULT_AUTHENTICATION_CLASSES‘: (
        ‘authenticator.utils.authentication.UserAuth‘,
        ‘authenticator.utils.authentication.UserAuth2‘,
    ),
}

~>.<~

原文地址:https://www.cnblogs.com/pungchur/p/12028381.html

时间: 2024-08-30 03:57:16

DRF Django REST framework 之 认证组件(五)的相关文章

DRF Django REST framework 之 视图组件(四)

引言 在我们有几十上百的视图类,都有get,post等方法,在功能类似时,会导致大量的重复代码出现,显然还有很多可以优化的地方.这也就有了视图组件,它的功能非常强大,能很好的优化接口逻辑. 视图组件 使用视图组件的mixin优化接口逻辑 导入 mixins 定义序列化类 定义视图类 # 1.导入mixins from rest_framework.mixins import ( ListModelMixin, CreateModelMixin, DestroyModelMixin, Update

轻轻松松学会 DRF Django REST framework

DRF Django REST framework 之 APIView(一) DRF Django REST framework 之 解析器(二) DRF Django REST framework 之 序列化(三) DRF Django REST framework 之 视图组件(四) 持续更新中.... 原文地址:https://www.cnblogs.com/pungchur/p/12028316.html

源码剖析Django REST framework的认证方式及自定义认证

源码剖析Django REST framework的认证方式 由Django的CBV模式流程,可以知道在url匹配完成后,会执行自定义的类中的as_view方法. 如果自定义的类中没有定义as_view方法,根据面向对象中类的继承可以知道,则会执行其父类View中的as_view方法 在Django的View的as_view方法中,又会调用dispatch方法. 现在来看看Django restframework的认证流程 Django restframework是基于Django的框架,所以基

DRF Django REST framework 之 频率,响应器与分页器组件(六)

频率组件 频率组件类似于权限组件,它判断是否给予请求通过.频率指示临时状态,并用于控制客户端可以向API发出的请求的速率. 与权限一样,可以使用多个调节器.API可能会对未经身份验证的请求进行限制,而对于经过身份验证的请求则进行限制较少. 例如,可以将用户限制为每分钟最多60个请求,每天最多1000个请求. 自定义频率组件 使用方式与权限,认证组件几乎相同 该方式没有DRF提供的方式简洁 import time import math from rest_framework import exc

DRF (Django REST framework) 框架介绍

Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 1 前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口. 2 前后端分离 在前后端分离的应用模式中,后端仅返

DRF (Django REST framework) 框架介绍(2)

环境安装与配置 DRF需要以下依赖: Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6) Django (1.10, 1.11, 2.0) DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需从新创建.(若没有Django环境,需要先创建环境安装Django) 1. 安装DRF pip install djangorestframework 2. 添加rest_framework应用 我们利用在Django框架学习中创建的demo工

django rest framework 用户认证

BaseAuthentication 类: django rest framework 通过 BaseAuthentication 实现认证功能 无论是自定义的认证类还是 rest framework 自带的认证类都应该继承 BaseAuthentication BaseAuthentication 中有两个方法 authenticate 和 authenticate_header, 其中 authenticate 方法必须实现 如果用户需要自定义认证方法则继承 BaseAuthenticati

django rest framework的十个组件

Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API .Django REST Framework可以在Django的基础上迅速实现API,并且自身还带有WEB的测试页面,可以方便的测试自己的API.简单说一下这个工具包的十个功能: 1.权限 2.认证 3.访问频率 4.序列化 (使用最多) 5.路由 6.视图 7.分页器 8.解析器 9.渲染器 10.版本 原文地址:https://www.cnblogs.com/zivli/p/10321771.htm

Django中rest_framework的认证组件,权限组件,频率组件,序列化组件的最简化版接口

url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.Login.as_view()), # Book表 url(r'^books/$',views.BookHandle.as_view({ 'get':'list', 'post':'create' })), url(r'^books/(?P<pk>\d+)/',views.BookHandle.as_view({ 'get':'retrieve