rest_framework认证流程

安装

pip3 install djangorestframework

 

使用

基于cbv使用rest_framework框架
from rest_framework.views import APIView  # rest_framework框架,继承View
class ApiTest(APIView): pass
当用户请求进来,执行父类的as_view方法, 返回view函数,执行dispatch方法,由于继承了APIView,会执行此类下边的dispatch方法
def dispatch(self, request, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs
    # 这里用initalize_request方法对原生的request进行加工
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers  # deprecate?
    try:
        # 对加工之后的request处理,看下这里边的逻辑
        self.initial(request, *args, **kwargs)
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(),
                              self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        response = handler(request, *args, **kwargs)
    except Exception as exc:
        response = self.handle_exception(exc)
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response
可以看到,APIView类下的dispatch方法相比于View中的dispatch方法,除了反射请求还多了一些操作
比如,对本来的request用initialize_request方法进行了一些加工,封装了一些其他的属性,点开看,
    def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)

        return Request(
            request,
            parsers=self.get_parsers(),
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )
是利用Request类生成了一个新的对象,新的对象包含了原有的request属性,还有一些其他的属性,
这里看下authenticators,这个属性是用来认证的属性,
    def get_authenticators(self):
        """
        Instantiates and returns the list of authenticators that this view can use.
        """
        return [auth() for auth in self.authentication_classes]
返回了一个列表生成式,生成的里边是一个个的对象,self.authentication_classes点开之后是读取的rest_frame的配置文件
class APIView(View):
    # The following policies may be set at either globally, or per-view.
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES #这里
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
如果我们在我们自己的类里边写入authentication_classes参数,就可以读取我们自己设置的,不用APIView下边的
from rest_framework.authentication import BasicAuthentication
class ApiTest(APIView):
    authentication_classes = [BasicAuthentication] 
到这里,我们已经大概知道dispatch对request进行了一些封装,接下来看下边的代码
def dispatch(self, request, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs
    # 这里用initalize_request方法对原生的request进行加工
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request  # 赋值
    self.headers = self.default_response_headers  # deprecate?
------------------------------------------------------------------------------------------- try: # 对加工之后的request处理,看下这里边的逻辑 self.initial(request, *args, **kwargs) if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
 try下边的initial方法,把封装了数据之后的request当参数,我们点开这个方法
    def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        """
        self.format_kwarg = self.get_format_suffix(**kwargs)

......
self.perform_authentication(request) # 封装过数据之后的request,认证用 self.check_permissions(request) self.check_throttles(request)

 

发现有一个perform_authentication方法,点开这个方法里边执行了user属性方法
@property
    def user(self):
        """
        Returns the user associated with the current request, as authenticated
        by the authentication classes provided to the request.
        """
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate() # 查看下这个方法
        return self._user

 

authenticate
    def _authenticate(self):
        """
        Attempt to authenticate the request using each authentication instance
        in turn.
        """
        for authenticator in self.authenticators: # 之前封装的认证对象
            try:
                user_auth_tuple = authenticator.authenticate(self) # 认证是否登录的方法,成功返回元组,失败报错
            except exceptions.APIException:
                self._not_authenticated()
                raise

            if user_auth_tuple is not None:
                self._authenticator = authenticator
                self.user, self.auth = user_auth_tuple
                return

        self._not_authenticated()

 

 

修改authentacate方法,实现验证功能

from django.shortcuts import HttpResponse
import json

from rest_framework.views import APIView  # rest_framework框架,继承View
from rest_framework.authentication import BasicAuthentication
from rest_framework import exceptions  # 验证失败触发异常


class Myauthentication(object):
    def authenticate(self, request):
        username = request._request.GET.get("username")  # 验证成功返回元组
        if not username:
            raise exceptions.AuthenticationFailed("用户名未登录")  # 无返回验证失败,触发异常
        return ("status",1)

    def authenticate_header(self, val):
        pass


class ApiTest(APIView):
    authentication_classes = [Myauthentication]  # 通过自定义的类做认证

    def get(self, request, *args, **kwargs):  # 用于处理get请求
        print(request)
        res = {
            "code": 1000,
            "msg": "hello world"
        }
        return HttpResponse(json.dumps(res))

    def post(self, request, *args, **kwargs):
        return HttpResponse("post")

    def put(self, request, *args, **kwargs):
        return HttpResponse("put")

    def delete(self, request, *args, **kwargs):
        return HttpResponse("delete")

 

转载于:https://www.cnblogs.com/ligiao/p/11493814.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值