Restframework的认证,权限,限制,分页
2018-08-05 07:51:07来源:博客园 阅读 ()
1.认证
流程:请求到达REST framework的时候,会对request进行二次封装,在封装的过程中会对客户端发送过来的request封装进认证,选择,解析等功能。request方法封装完成之后,执行initial方法时,又会再次对客户端的请求执行认证操作,确保请求的合法性
生命周期:
发送请求-->Django的wsgi-->中间件-->路由系统_执行CBV的as_view(),就是执行内部的dispath方法-->在执行dispath之前,有版本分析 和 渲染器-->在dispath内,对request封装-->版本-->认证-->权限-->限流-->视图-->如果视图用到缓存( request.data or request.query_params )就用到了 解析器-->视图处理数据,用到了序列化(对数据进行序列化或验证) -->视图返回数据可以用到分页
自定义认证:
models.py(创建完后自行添加几条数据)
from django.db import models # 用户信息 class UserInfo(models.Model): username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=32) # 小整数字段 type = models.SmallIntegerField( choices=((1,"普通用户"),(2,"VIP用户")), default=1 ) # 用户认证 class Token(models.Model): token = models.CharField(max_length=32) user = models.OneToOneField(to="UserInfo") # 评论表 class Comment(models.Model): content = models.CharField(max_length=128) user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, default=1)
url.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'login/$', views.LoginView.as_view()), ] from rest_framework.routers import DefaultRouter router = DefaultRouter() # 注册路由,表示路径comment对应视图函数CommentViewSet router.register(r'comment', views.CommentViewSet) urlpatterns += router.urls
views.py
import time import hashlib from app01 import models from rest_framework.views import APIView from rest_framework.response import Response from app01 import app01_serializers # 自定义的序列化 from rest_framework.viewsets import ModelViewSet # 生成token函数 def get_token_code(username): """ 根据用户名和时间戳生成用户登陆成功的随机字符串 :param username:字符串格式的用户名 :return:字符串格式的token """ timestamp = str(time.time()) m = hashlib.md5(bytes(username,encoding="utf-8")) m.update(bytes(timestamp,encoding="utf-8")) return m.hexdigest() class LoginView(APIView): """ 1. 接收用户发过来(POST)的用户名和密码数据 2. 校验用户名密码是否正确 - 成功就返回登陆成功(发Token) - 失败就返回错误提示 """ def post(self,request): res = {"code":0} username = request.data.get("username") password = request.data.get("password") user_obj = models.UserInfo.objects.filter( username=username, password=password, ).first() if user_obj: token = get_token_code(username) # 保存token # 如果有记录就更新defaults里传的参数, 没有记录就用defaults里传的参数创建一条数据 models.Token.objects.update_or_create(defaults={"token": token}, user=user_obj) # 将token返回给用户 res["token"] = token else: res["token"] = 1 res["error"] = "用户名或密码错误" return Response(res) # 对文章进行增删改查操作 class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer
app01_serializers.py(app下创建的py文件)
from app01.models import Comment from rest_framework import serializers class CommentSerializer(serializers.ModelSerializer): class Meta: model = Comment fields = "__all__"
通过在postman上模拟post发送请求登录,如果用户名和密码正确的话,会生成token值,下次该用户再登录时,token的值就会更新
当用户名或密码错误时,抛出异常
上面看是没有什么问题,但是任何用户都能访问评论,如何只让登陆用户查看信息呢?这里我们就需要添加一个认证类
在app01(应用名)目录下创建目录utils,在此目录下创建auth.py,用于放置自定义的认证类
auth.py
from app01 import models from rest_framework.authentication import BaseAuthentication # 导入处理REST框架引发的异常的模块 from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication): # 重写BaseAuthentication里的方法 def authenticate(self, request): if request.method in ["POST","PUT",]: # 取token值 token = request.data.get("token") # 去数据库查询有没有这个token token_obj = models.Token.objects.filter(token=token).first() if token_obj: # token_obj有2个属性,详见models.py中的Token。 # return后面的代码,相当于分别赋值。例如a=1,b=2等同于a,b=1,2 # return多个值,返回一个元组 # 在rest framework内部会将这两个字段赋值给request,以供后续操作使用 return token_obj.user, token else: raise AuthenticationFailed("无效的token") else: return None, None
views.py下的CommentViewSet类:
# app01.utils.auth表示app01目录下的utils下的auth.py from app01.utils.auth import MyAuth class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [MyAuth, ] # 局部使用认证方法MyAuth
验证:发送一个空的post请求或者错误的post请求
发送正确的post请求:
## 以上只是做了一个局部的认证,对于全局认证:
需要在setting中配置:
REST_FRAMEWORK = { # 表示app01-->utils下的auth.py里面的MyAuth类 "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.auth.MyAuth", ] }
这时候CommentViewSet中的authentication_classes就可以注释掉了,效果也是一样的
2.权限
自定义我们的权限,如只有让VIP用户才能看的内容
3.限制
4.分页
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:python学习笔记
下一篇:面向对象进阶
- Django框架之DRF 认证组件源码分析、权限组件源码分析、频率 2019-07-24
- 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源 2019-07-24
- odoo 权限配置讲解 2019-05-08
- odoo权限配置讲解2 2019-05-08
- day91 DjangoRestFramework学习三之认证组件、权限组件、频 2019-04-25
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash