DRF学习——认证组件(二)

一丶简介

本篇文章主要是通过一个实际的案例来介绍drf的认证组件如何使用

二、代码

在第一节的基础上修改代码

 之所以有三个认证组件,是因为访问api接口的时候,携带token有两种方式,第一种是携带字url中,第二种是携带在请求头中,而第三种则是没有认证通过返回错误使用,前两者的return皆为None,根据上一节源码的分析可知,返回值为None则会跳到下一个认证组件,当跳到第三个认证组件时,便报错跳出,下面为代码:

# 路径:ext/auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from api import models


class QueryParamsAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 用户认证步骤:
        # 1.读取请求传递的token
        # 2.校验合法性
        # 3.三种返回值
        #   3.1 认证成功,返回元组(11,22)     11,22分别存入request.user和request.auth
        #   3.2 认证失败,抛出异常   返回错误信息
        #   3.3 返回None(不常用),用于多个认证类

        # /xxx/xxx/?token=1231dd
        # token = request._request.GET.get('token')
        # drf的request源码中的query_params=_request.GET
        token = request.query_params.get('token')
        if not token:
            return
        user_object = models.UserInfo.objects.filter(token=token).first()
        # 这里获取到请求传递的token后,理应校验合法性,不过这里先略去
        if user_object:
            # request.user和request.auth
            return user_object, token
        return
        # raise AuthenticationFailed("认证失败")
        # 如果返回字符串,字符串会放入detail中,如果返回字典,则该字典会替代detail

    def authenticate_header(self, request):
        return 'API'


class HeaderAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 用户认证步骤:
        # 1.读取请求传递的token
        # 2.校验合法性
        # 3.三种返回值
        #   3.1 认证成功,返回元组(11,22)     11,22分别存入request.user和request.auth
        #   3.2 认证失败,抛出异常   返回错误信息
        #   3.3 返回None(不常用),用于多个认证类

        # /xxx/xxx/?token=1231dd
        # token = request._request.GET.get('token')
        # drf的request源码中的query_params=_request.GET
        token = request.META.get('HTTP_AUTHORIZATION')
        if not token:
            return
        user_object = models.UserInfo.objects.filter(token=token).first()
        # 这里获取到请求传递的token后,理应校验合法性,不过这里先略去
        if user_object:
            # request.user和request.auth
            return user_object, token
        # raise AuthenticationFailed("认证失败")
        # 如果返回字符串,字符串会放入detail中,如果返回字典,则该字典会替代detail
        return

    def authenticate_header(self, request):
        return 'API'


class NoAuthentication(BaseAuthentication):
    def authenticate(self, request):
        raise AuthenticationFailed({"code": 202, "msg": "认证失败"})

    def authenticate_header(self, request):
        return 'API'
# api/models.py
from django.db import models


class UserInfo(models.Model):
    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    # 临时方式、jwt
    token = models.CharField(verbose_name='TOKEN', max_length=64, null=True, blank=True)
# api/views.py
import uuid
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request

from api import models


class UserView(APIView):

    def get(self, request):
        print(request.user)
        print(request.auth)
        return Response("UserView")


class LoginView(APIView):
    authentication_classes = []

    def post(self, request):
        # 1.接受用户名和密码
        print(request.data)
        user = request.data.get('username')
        pwd = request.data.get('password')

        # 2.数据库校验
        user_object = models.UserInfo.objects.filter(username=user, password=pwd).first()
        if not user_object:
            return Response({'code': 201, "msg": "用户名密码错误"})
        token = str(uuid.uuid4())
        user_object.token = token
        user_object.save()
        return Response({'code': 0, 'data': token})


class OrderView(APIView):

    def get(self, request):
        self.dispatch()
        return Response("OrderView")

三、测试接口

①访问login接口获取token

 ②不携带token访问user

③请求头携带token访问user

④url携带token访问user

 

可见已经实现认证功能 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hemameba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值