S11 day 96 RestFramework 之认证权限
一、设计一个简易的登录
1. 建立一个模型
class UserInfo(models.Model):
username =models.CharField(max_length=)
password =models.CharField(max_length=) type =models.SmallIntegerField(
choices=((,"普通用户"),(,"vip用户")),
default=
) class Token(models.Model):
token =models.CharField(max_length=)
user=models.OneToOneField(to="UserInfo")
makemigration ,migrate ,添加数据
2.设计url
url(r'login/$', views.LoginView.as_view()),
3.制作一个视图类进行简单登录
lass LoginView(APIView):
def post(self,request):
print(request.data)
res={"code":}
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
res["data"] ="登录成功" else:
#登录失败
res["code"] =
res["error"] = "用户名或密码错误"
return Response(res)
输出结果:

二 、认证
4. 为视图增加一个生成token的功能
#生成Token的函数
def get_token_code(username):
"""
根据用户名和时间戳生成用户登录成功的随机字符串
:param username: 字符串格式的用户名
:return: 返回字符串格式的token
"""
import time,hashlib
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):
def post(self,request):
print(request.data)
res={"code":}
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
token= get_token_code(username)
#将token保存
#用户user =user_obj 这个条件去token表里查询,如果有的话就更新default里的参数,没有记录就创建
models.Token.objects.update_or_create(defaults={"token":token},user =user_obj)
res["data"] ="登录成功" else:
#登录失败
res["code"] =
res["error"] = "用户名或密码错误"
return Response(res)

5. 测试token能否生成。


6. get请求里的token和数据库里的token进行对比.


7.认证的代码
红色部分为局部认证
from app01.utils1.auth import MyAuth
from rest_framework.viewsets import ModelViewSet
class CommentView(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth,] #视图认证,属于局部认证.
全局认证写在settings里
REST_FRAMEWORK = {
# #关于认证的全局配置.
"DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.MyAuth",]
}
#登录视图
class LoginView(APIView):
def post(self,request):
print(request.data)
res={"code":}
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
token= get_token_code(username)
#将token保存
#用户user =user_obj 这个条件去token表里查询,如果有的话就更新default里的参数,没有记录就创建
models.Token.objects.update_or_create(defaults={"token":token},user =user_obj)
res["data"] ="登录成功" else:
#登录失败
res["code"] =
res["error"] = "用户名或密码错误"
return Response(res)
"""
自定义的认证都放在这里
"""
from rest_framework.authentication import BaseAuthentication
from app01 import models
from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication):
def authenticate(self, request):
if request.method in ["POST","PUT","DELETE"]:
token =request.data.get("token")
#去数据库中查找有没有这个这个token
token_obj =models.Token.objects.filter(token=token).first()
if token_obj:
return token_obj.user,token
else :
raise AuthenticationFailed("无效的token") else:return None,None
三、权限
"""
自定义的权限类 # """ from rest_framework.permissions import BasePermission
class Mypermission(BasePermission):
message={}
def has_permission(self, request, view):
"""
判断该用户有没有权限
"""
#判断用户是不是vip用户
#如果是vip用户就返回trun
#普通用户就返回false
print("requet--->",request.user.username)
print("requet--->",request.user.type)
if request.user.type ==:#是vip用户
return True
else:
return False def has_object_permission(self, request, view, obj):
"""
判断当前评论的作者是不是当前的用户
只有作者自己才能评论自己的文章 """
print("这是在自定义权限类里的")
print(obj)
if request.method in ["PUT","DELETE"]:
if obj.user == request.user:
#当前要删除评论的作者就是当前登录的账号
return True
else:
return False
else:
return True
四、限制 频率
方法1 .
'''
自定义的访问限制类 第一种方法
'''
from rest_framework.throttling import BaseThrottle
import time
VISIT = { }#{ "127.0.0.1":[,,]} class MyThrottle(BaseThrottle):
def allow_request(self, request, view):
"""
返回true 就表示放行,返回false表示被限制....
:param request:
:param view:
:return:
"""
# . 获取当前的访问ip
ip=request.META.get("REMOTE_ADDR")
print("这是自定义限制类中的allow_request")
print(ip)
#. 获取当前的时间
now =time.time
#判断当前ip是否有访问记录
if ip not in VISIT:
VISIT[ip]=[] #初始化一个空的访问列表
#把这一次的访问时间交到访问历史列表的第一位
history =VISIT[ip]
while history and now - history[-]>:
history.pop()
#判断最近一分钟的访问次数是否超过了阈值(3次)
if len(history)>=:
return False
else:
VISIT[ip].insert(, now)
return True


方法2.
'''
自定义的访问限制类 第二种方法 ,采用源码的代码
'''
# VISIT2={
# "XXX":{
# ip:[]
# }
# }
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope ="xxx"
def get_cache_key(self, request, view):
return self.get_ident(request) #求当前访问的ip


S11 day 96 RestFramework 之认证权限的更多相关文章
- rest-framework框架 -- 认证权限流程源码
认证权限 解析BaseAuthentication源码 # 做认证权限 from rest_framework import exceptions from ..models import * cla ...
- rest-framework框架——认证、权限、频率组件
一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...
- restful知识点之三restframework认证-->权限-->频率
认证.权限.频率是层层递进的关系 权限业务时认证+权限 频率业务时:认证+权限+频率 局部认证方式 from django.conf.urls import url,include from djan ...
- Restframework的认证,权限,节流
1.认证 流程:请求到达REST framework的时候,会对request进行二次封装,在封装的过程中会对客户端发送过来的request封装进认证,选择,解析等功能.request方法封装完成之后 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限
开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...
- Kafka认证权限配置(动态添加用户)
之前写过一篇Kafka ACL使用实战,里面演示了如何配置SASL PLAINTEXT + ACL来为Kafka集群提供认证/权限安全保障,但有一个问题经常被问到:这种方案下是否支持动态增加/移除认证 ...
- django 之(三) --- 认证|权限
用户模块 登陆注册1:Django2.0 [ 1:N ] user/url.py from django.urls import path from user.views0 import UserT ...
- 实战-DRF快速写接口(认证权限频率)
实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...
- 基于asp.net MVC 的服务器和客户端的交互(二)之获取Oauth 2.0认证权限
基本Web API的ASP.NET的Oauth2认证 增加Token额外字段 增加Scope授权字段 持久化Token 设计Token的时间间隔 刷新Token后失效老的Token 自定义验证[重启I ...
随机推荐
- 2-string相关函数
string真的很好用,希望通过逐步的学习逐渐掌握的string的用法: 1. append() -- 在字符串的末尾添加字符 2. find() -- 在字符串中查找字符串 4. insert() ...
- 《Google软件测试之道》摘录
以下是最近看的一本书<Google软件测试之道>里的一些摘录,收获很多. 1.讨论测试开发比并没有什么意义,如果你是一名开发人员,同时也是一名测试人员,如果你的职位头衔上有测试的字样,你的 ...
- ==和equals方法:
Java程序中判断两个变量是否相等有两种方式: 一.利用 == 运算符: 1.1.如果两个变量是基本类型变量,且都是数值型(不一定要求数值类型完全相同),则只要两个变量的值相同,就返回true 1.2 ...
- stl string 小练习
最近没啥可写的 这里写下做的STL小练习 作为记录 去除指定字符串中的空格 获取文件名并根据名字创建临时文件,以TMP后缀结尾,已经为TMP后缀结尾文件则创建以XXX后缀结尾文件 读取一行输入内容 ...
- UUID含义及ubuntu配置系统默认JDK
UUID含义是通用唯一识别码(Universally Unique Identifier) GUID是一个128位长的数字,一般用16进制表示.算法的核心思想是结合机器的网卡.当地时间.一个随即数来生 ...
- Devexpress VCL Build v2013 vol 14.1.3 发布
我修,我修,修修修. New Major Features in 14.1 What's New in VCL Products 14.1 Breaking Changes To learn abou ...
- 第一章:模型层model layer
1.模型和字段 (1)基本的原则如下: 每个模型在Django中的存在形式为一个Python类 每个模型都是django.db.models.Model的子类 模型的每个字段(属性)代表数据表的某一列 ...
- DevExpress gridcontrol Master-Detail绑定到对象类型
数据库:C_ProductPlan ,C_ProductPlanItemDTO定义:(实现每个计划条目-Master,对应多个ProcessInfo-Detail) [DataContract] [S ...
- [转]Go与C语言的互操作
Go有强烈的C背景,除了语法具有继承性外,其设计者以及其设计目标都与C语言有着千丝万缕的联系.在Go与C语言互操作(Interoperability)方面,Go更是提供了强大的支持.尤其是在Go中使用 ...
- linux将程序扔到后台并获取程序的进程号
我们经常需要写一些执行时间较长的程序,但是如果在程序执行过程中超时了,有许多原因,可能是程序已经挂起了,这时就需要杀死这样的进程,则可以通过如下的命令执行: java -jar TestProcess ...
