码迷,mamicode.com
首页 > 其他好文 > 详细

认证与权限组件

时间:2020-06-06 21:56:28      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:tuple   自定义   error   用户名   isp   用户登录   rand   imp   用户   

一、认证组件

局部视图认证

    url(r^login/$, views.LoginView.as_view(),name="login"),

models.py

from django.db import models

class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)

class Token(models.Model):
    user=models.OneToOneField("User")
    token = models.CharField(max_length=128)

    def __str__(self):
        return self.token

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

先看认证组件源代码流程:

当用户登录的时候会走APIView类下的dispatch

class APIView(View):
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES#
    
    # for authenticator in self.authenticators:中的authenticators最终来源于这里
    def get_authenticators(self):# (12)

        return [auth() for auth in self.authentication_classes] #[TokenAuthor()]  (13)
        #如果我们定义了authentication_classes就使用自己定义的,没有定义就使用上面的
        #最终生成的列表中放着一个个认证类的实例对象

    def perform_authentication(self, request):# (4)

        request.user #查找request:->perform_authentication(self, request)->initial(self, request, *args, **kwargs)
        #->self.initial(request, *args, **kwargs)->dispatch(self, request, *args, **kwargs)最后找到的是dispatch类下
        #的request方法:request = self.initialize_request(request, *args, **kwargs),这个request是initialize_request类
        #下Request的实例化对象,可知user是Request类中的静态方法
        # 实例化对象,而且是新构建的request,  (5)
        #

    def initialize_request(self, request, *args, **kwargs):#
        return Request(#
            request,#
            authenticators=self.get_authenticators(),  #[TokenAuthor()] (11)
        )

    def initial(self, request, *args, **kwargs):# (2)
        #认证组件
        self.perform_authentication(request) (3)
      #权限组件
        self.check_permissions(request)
        #访问频率组件
        self.check_throttles(request)

    def dispatch(self, request, *args, **kwargs):#
        request = self.initialize_request(request, *args, **kwargs)#
        self.request = request#

        try:
            self.initial(request, *args, **kwargs)#  (1)

#request.py
class Request:
    def __init__(self, request, parsers=None, authenticators=None,):
        self._request = request

        self.authenticators = authenticators or () (10)  #这里我们自定义了,在Request类实例化的时候通过参数的方式传进来了  
        #authenticators=self.get_authenticators()

    @property
    def user(self):  (6)
        if not hasattr(self, _user):
            with wrap_attributeerrors():
                self._authenticate()  (7)
        return self._user

    #认证所有的源代码都在这
    def _authenticate(self):# (8)
        for authenticator in self.authenticators: #[TokenAuthor()]  (9)
            #查找authenticators:->_authenticate->user->Request(object)->get_authenticators
            #authenticator就是我们自定制的认证类的实例对象
            try:
                user_auth_tuple = authenticator.authenticate(self)
                #类下的实例对象调自己的方法本不需要传self,这里的self是新的request对象

            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

使用:

在app01.service.auth.py:

from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication #
class TokenAuth(BaseAuthentication):#
    def authenticate(self,request):#
        token=request.GET.get("token")#
        token_obj=Token.objects.filter(token=token).first()#
        if not token_obj:#
            raise exceptions.AuthenticationFailed("验证失败!")
        else:
            return token_obj.user.name,token_obj.token#

views.py

#生成token随机字符串
def get_random_str(user):
    import hashlib,time
    ctime=str(time.time())

    md5=hashlib.md5(bytes(user,encoding="utf8")) #构建一个md5对象,使用user加盐处理
    md5.update(bytes(ctime,encoding="utf8"))

    return md5.hexdigest()
#登陆验证
from .models import User
from app01.service.auth import *
class LoginView(APIView): authentication_classes = [TokenAuth, ] # [TokenAuth(),] def post(self,request):# name=request.data.get("name") pwd=request.data.get("pwd") user=User.objects.filter(name=name,pwd=pwd).first() res = {"state_code": 1000, "msg": None}# if user: random_str=get_random_str(user.name) #取随机字符串 token=Token.objects.update_or_create(user=user,defaults={"token":random_str}) #更新token表 res["token"]=random_str# else: res["state_code"]=1001 #错误状态码 res["msg"] = "用户名或者密码错误"# import json return Response(json.dumps(res,ensure_ascii=False))#

以上只是对登录进行了认证

2 全局视图认证组件 

settings.py配置如下:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.TokenAuth",]
}

 

认证与权限组件

标签:tuple   自定义   error   用户名   isp   用户登录   rand   imp   用户   

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13056424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!