认证与权限组件
Posted zh-xiaoyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了认证与权限组件相关的知识,希望对你有一定的参考价值。
一、认证组件
1 局部视图认证
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",] }
以上是关于认证与权限组件的主要内容,如果未能解决你的问题,请参考以下文章