rest_framework之认证

本文介绍了rest_framework中的认证组件,包括认证简介、局部使用方法和全局使用策略。在局部使用中,详细阐述了models层、认证类的创建以及view层的应用,并提及了不存数据库的token验证。全局使用部分则对认证的顺序进行了说明,强调了视图类和settings配置的认证类优先级。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rest_framework之认证组件

一 认证简介

只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件

二 局部使用

(1)models层:

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')
    #与user表建一对一的关系
    token=models.CharField(max_length=64)

(2)新建认证类(验证通过return两个参数)

from rest_framework.authentication import BaseAuthentication
class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if token_obj:
            return  #这里可以返回数据,第一个在需要认证的函数中为user,第二位auth可以取出
        else:
            raise AuthenticationFailed('认证失败')
            #如果报错可以返回这个异常
    def authenticate_header(self,request): 
        #如果不继承BaseAuthentication类,则需写这个函数
        pass

(3)view层

def get_random(name):
    '''用来生成hsah值'''
    import hashlib
    import time
    md=hashlib.md5()
    md.update(bytes(str(time.time()),encoding='utf-8'))
    md.update(bytes(name,encoding='utf-8'))
    return md.hexdigest()
class Login(APIView):
    '''验证用户post请求的登陆'''
    def post(self,reuquest):
        back_msg={'status':1001,'msg':None}
        try:
            name=reuquest.data.get('name')
            pwd=reuquest.data.get('pwd')
            user=models.User.objects.filter(username=name,password=pwd).first()
            if user:
                token=get_random(name)
                # 如果用户验证完毕,则存入token
                models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
                back_msg['status']='1000'
                back_msg['msg']='登录成功'
                back_msg['token']=token
                # 将token值返回前端
            else:
                back_msg['msg'] = '用户名或密码错误'
        except Exception as e:
            back_msg['msg']=str(e)
            # 捕获异常返回
        return Response(back_msg)



class Course(APIView):
   '''给视图类认证'''
    authentication_classes = [TokenAuth, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

附:不存数据库的token验证

def get_token(id,salt='123'):
    '''用来返回自定义的token值'''
    import hashlib
    md=hashlib.md5()
    md.update(bytes(str(id),encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))

    return md.hexdigest()+'|'+str(id)

def check_token(token,salt='123'):
    '''用来验证前台返回的token值'''
    ll=token.split('|')
    import hashlib
    md=hashlib.md5()
    md.update(bytes(ll[-1],encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    if ll[0]==md.hexdigest():
        return True
    else:
        return False

class TokenAuth(BaseAuthentication):
    '''认证类'''
    def authenticate(self, request):
        token = request.GET.get('token')
        success=check_token(token)
        if success:
            return
        else:
            raise AuthenticationFailed('认证失败')
   
class Login(APIView):
   	'''登陆类'''
    def post(self,reuquest):
        back_msg={'status':1001,'msg':None}
        try:
            name=reuquest.data.get('name')
            pwd=reuquest.data.get('pwd')
            user=models.User.objects.filter(username=name,password=pwd).first()
            if user:
                
                token=get_token(user.pk)
                # 无需存入token
                # models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
                back_msg['status']='1000'
                back_msg['msg']='登录成功'
                back_msg['token']=token
            else:
                back_msg['msg'] = '用户名或密码错误'
        except Exception as e:
            back_msg['msg']=str(e)
        return Response(back_msg)

class Course(APIView):
    authentication_classes = [TokenAuth, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

总结:局部使用,只需要在视图类里加入:

authentication_classes = [TokenAuth, ]

三 全局使用

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
#局部不用认证的情况可以设置authentication_classes = []

四 源码分析

#Request对象的user方法
@property
def user(self):
the authentication classes provided to the request.
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

def _authenticate(self):
        for authenticator in self.authenticators:
            try:
                user_auth_tuple = authenticator.authenticate(self)
            except exceptions.APIException:
                self._not_authenticated()
                raise
            #认证成功,可以返回一个元组,但必须是最后一个验证类(authentication_classes)才能返回
            if user_auth_tuple is not None:
                self._authenticator = authenticator
                self.user, self.auth = user_auth_tuple
                return

        self._not_authenticated()

self.authenticators

    def get_authenticators(self):
        return [auth() for auth in self.authentication_classes]
    # 将认证类拿到后进行实列化

认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类

### 实现JWT认证 为了实现JSON Web Token (JWT) 认证,在`settings.py`文件中需向Django REST框架的默认认证类列表添加`JSONWebTokenAuthentication`[^1]。 配置如下所示: ```python REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), } ``` 安装必要的包对于集成JWT至关重要。通过pip可以轻松完成DRF及其JWT支持库的安装[^4]。 ```bash python -m pip install djangorestframework python -m pip install djangorestframework-jwt ``` 当请求到达时,`request.user`属性会返回由当前请求的身份验证类所确认的相关用户对象[^3]。此过程涉及调用内部方法来处理实际的身份验证逻辑并设置用户实例。 创建视图函数或类时,可以通过装饰器或者基于类的方法限制访问权限,仅允许经过适当授权的用户继续操作。例如: ```python from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView class ExampleView(APIView): permission_classes = [IsAuthenticated] def get(self, request, format=None): content = {'message': 'Hello, you are authenticated!'} return Response(content) ``` 上述代码片段展示了如何定义一个简单的API端点,并确保只有已登录且有效令牌存在的客户端才能成功发起GET请求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值