认证组件

Django原生的authentic组件为我们的用户注册与登录提供了认证功能,十分的简介与强大。同样DRF也为我们提供了认证组件,一起来看看DRF里面的认证组件是怎么为我们工作的!
models.py
# 定义一个用户表和一个保存用户Token的表 class UserInfo(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=32) type = models.SmallIntegerField( choices=((1, '普通用户'), (2, 'VIP用户')), default=1 ) class Token(models.Model): user = models.OneToOneField(to='UserInfo') token_code = models.CharField(max_length=128)

15
1
# 定义一个用户表和一个保存用户Token的表

2
3
4
class UserInfo(models.Model):

5
    username = models.CharField(max_length=16)

6
    password = models.CharField(max_length=32)

7
    type = models.SmallIntegerField(

8
        choices=((1, '普通用户'), (2, 'VIP用户')),

9
        default=1

10
    )

11
12
13
class Token(models.Model):

14
    user = models.OneToOneField(to='UserInfo')

15
    token_code = models.CharField(max_length=128)

url
path('login/', views.LoginView.as_view()),

1
1
    path('login/', views.LoginView.as_view()),

views.py
# 视图主要处理用户名、密码是否正确,用户每一次请求都要带着专有token来! import hashlib, time from rest_framework.response import Response from rest_framework.views import APIView def get_random_token(username): """ 根据用户名和时间戳生成随机token :param username: :return: """ timestamp = str(time.time()) m = hashlib.md5(bytes(username, encoding="utf8")) m.update(bytes(timestamp, encoding="utf8")) return m.hexdigest() class LoginView(APIView): """ 校验用户名密码是否正确从而生成token的视图 """ def post(self, request): res = {"code": 0} print(request.data) username = request.data.get("username") password = request.data.get("password") user = models.UserInfo.objects.filter(username=username, password=password).first() if user: # 如果用户名密码正确 token = get_random_token(username) models.Token.objects.update_or_create(defaults={"token_code": token}, user=user) res["token"] = token else: res["code"] = 1 res["error"] = "用户名或密码错误" return Response(res)

38
1
# 视图主要处理用户名、密码是否正确,用户每一次请求都要带着专有token来!

2
import hashlib, time

3
from rest_framework.response import Response

4
from rest_framework.views import APIView

5
6
7
def get_random_token(username):

8
    """

9
    根据用户名和时间戳生成随机token

10
    :param username:

11
    :return:

12
    """

13
    timestamp = str(time.time())

14
    m = hashlib.md5(bytes(username, encoding="utf8"))

15
    m.update(bytes(timestamp, encoding="utf8"))

16
    return m.hexdigest()

17
18
19
class LoginView(APIView):

20
    """

21
    校验用户名密码是否正确从而生成token的视图

22
    """

23
    def post(self, request):

24
        res = {"code": 0}

25
        print(request.data)

26
        username = request.data.get("username")

27
        password = request.data.get("password")

28
29
        user = models.UserInfo.objects.filter(username=username, password=password).first()

30
        if user:

31
            # 如果用户名密码正确

32
            token = get_random_token(username)

33
            models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)

34
            res["token"] = token

35
        else:

36
            res["code"] = 1

37
            res["error"] = "用户名或密码错误"

38
        return Response(res)

定义认证类model_serializer.py
# 这一步是要对着源码才能写出来 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication): def authenticate(self, request): if request.method in ["POST", "PUT", "DELETE"]: request_token = request.data.get("token", None) if not request_token: raise AuthenticationFailed('缺少token') token_obj = models.Token.objects.filter(token_code=request_token).first() if not token_obj: raise AuthenticationFailed('无效的token') return token_obj.user.username, None else: return None, None

18
1
# 这一步是要对着源码才能写出来

2
from rest_framework.authentication import BaseAuthentication

3
from rest_framework.exceptions import AuthenticationFailed

4
5
6
class MyAuth(BaseAuthentication):

7
    def authenticate(self, request):

8
        if request.method in ["POST", "PUT", "DELETE"]:

9
            request_token = request.data.get("token", None)

10
            if not request_token:

11
                raise AuthenticationFailed('缺少token')

12
            token_obj = models.Token.objects.filter(token_code=request_token).first()

13
            if not token_obj:

14
                raise AuthenticationFailed('无效的token')

15
            return token_obj.user.username, None

16
        else:

17
            return None, None

18

全局配置
# 在settings.py中配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ] }

4
1
# 在settings.py中配置

2
REST_FRAMEWORK = {

3
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ]

4
}

权限组件

只有vip才能看的内容
自定义权限类
# 自定义权限类 from rest_framework.permissions import BasePermission class MyPermission(BasePermission): message = 'VIP用户才能访问' def has_permission(self, request, view): """ 自定义权限只有VIP用户才能访问 """ # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user if request.user and request.user.type == 2: # 如果是VIP用户 return True else: return False

15
1
# 自定义权限类

2
from rest_framework.permissions import BasePermission

3
4
class MyPermission(BasePermission):

5
    message = 'VIP用户才能访问'

6
7
    def has_permission(self, request, view):

8
        """

9
        自定义权限只有VIP用户才能访问

10
        """

11
        # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user

12
        if request.user and request.user.type == 2:  # 如果是VIP用户

13
            return True

14
        else:

15
            return False

视图级别配置
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [MyAuth, ] permission_classes = [MyPermission, ]

6
1
class CommentViewSet(ModelViewSet):

2
3
    queryset = models.Comment.objects.all()

4
    serializer_class = app01_serializers.CommentSerializer

5
    authentication_classes = [MyAuth, ]

6
    permission_classes = [MyPermission, ]

全局配置
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ], "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ] }

4
1
REST_FRAMEWORK = {

2
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],

3
    "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]

4
}

频率组件

频率:限制用户访问网站的频率
自定义限制类
VISIT_RECORD = {} # 自定义限制 class MyThrottle(object): def __init__(self): self.history = None def allow_request(self, request, view): """ 自定义频率限制60秒内只能访问三次 """ # 获取用户IP ip = request.META.get("REMOTE_ADDR") timestamp = time.time() if ip not in VISIT_RECORD: VISIT_RECORD[ip] = [timestamp, ] return True history = VISIT_RECORD[ip] self.history = history history.insert(0, timestamp) while history and history[-1] < timestamp - 60: history.pop() if len(history) > 3: return False else: return True def wait(self): """ 限制时间还剩多少 """ timestamp = time.time() return 60 - (timestamp - self.history[-1])

33
1
VISIT_RECORD = {}

2
# 自定义限制

3
class MyThrottle(object):

4
5
    def __init__(self):

6
        self.history = None

7
8
    def allow_request(self, request, view):

9
        """

10
        自定义频率限制60秒内只能访问三次

11
        """

12
        # 获取用户IP

13
        ip = request.META.get("REMOTE_ADDR")

14
        timestamp = time.time()

15
        if ip not in VISIT_RECORD:

16
            VISIT_RECORD[ip] = [timestamp, ]

17
            return True

18
        history = VISIT_RECORD[ip]

19
        self.history = history

20
        history.insert(0, timestamp)

21
        while history and history[-1] < timestamp - 60:

22
            history.pop()

23
        if len(history) > 3:

24
            return False

25
        else:

26
            return True

27
28
    def wait(self):

29
        """

30
        限制时间还剩多少

31
        """

32
        timestamp = time.time()

33
        return 60 - (timestamp - self.history[-1])

视图级别配置
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer throttle_classes = [MyThrottle, ]

x
1
class CommentViewSet(ModelViewSet):

2
3
    queryset = models.Comment.objects.all()

4
    serializer_class = app01_serializers.CommentSerializer

5
    throttle_classes = [MyThrottle, ]

全局配置
# 在settings.py中设置rest framework相关配置项 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ], "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ] "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ] }

1
# 在settings.py中设置rest framework相关配置项

2
REST_FRAMEWORK = {

3
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],

4
    "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]

5
    "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ]

6
}

认证组件的源码阅读

新构建的request里面的源码的user方法

源码走到了这里其实就已经需要我们自己来进行认证了。就可以对前端的请求进行认证,到底该怎么认证,还得继续往下走!

 

权限组件的源码阅读

相比较与认证组件,权限组件就更加的简洁了

频率组件的注意部分

转载于:https://www.cnblogs.com/pontoon/p/10217414.html

04,认证、权限、频率相关推荐

  1. DRF的版本控制,认证,权限和频率限制

    版本控制 源码解析 这个框架提供了一些些版本的控制方法就在,rest_framework.versioning里 如何使用: settings.py里 REST_FRAMEWORK = {# 默认使用 ...

  2. SAP云解决方案和企业本地部署(On-Premise)混合架构下的安全认证权限管理

    SAP云解决方案和企业本地部署(On-Premise)混合架构下的安全认证权限管理 参考文章: (1)SAP云解决方案和企业本地部署(On-Premise)混合架构下的安全认证权限管理 (2)http ...

  3. 详解比springSecurity和shiro更简单优雅的轻量级Sa-Token框架,比如登录认证,权限认证,单点登录,OAuth2.0,分布式Session会话,微服务网关鉴权

    文章目录 1. 技术选型 2. Sa-Token概述 2.1 简单介绍 2.2 登录认证 2.3 权限认证 3. 功能一览 4. Sa-Token使用 4.1 引入Sa-Token依赖 4.2 Sa- ...

  4. rest_framework07:权限/频率/过滤组件/排序/异常处理封装Response对象

    权限 写一个类,继承BasePermission,如果通过返回True,否则False 这里需要配合认证使用,否则没有user_type属性. from rest_framework.permissi ...

  5. 【Mongodb】用户和认证 权限总结

       开启MongoDB服务时不添加任何参数时,默认是没有权限验证的,登录的用户可以对数据库任意操作而且可以远程访问数据库!    在刚安装完毕的时候MongoDB都默认有一个admin数据库,此时a ...

  6. ThinkJS入门+实例(实现认证权限等基本功能)

    这是一篇关于ThinkJS框架的文章,因为网上对于该框架的介绍非常少,所以在这里通俗讲解一下自己对该框架基本的认识并且提供了一个练习基本功能的项目. 因为这是基于Node.js的框架,所以先带新手入门 ...

  7. 复习Java第一个项目学生信息管理系统 04(权限管理和动态挂菜单功能) python简单爬数据实例Java面试题三次握手和四次挥手生活【记录一个咸鱼大学生三个月的奋进生活】016

    记录一个咸鱼大学生三个月的奋进生活016 复习Java(学生信息管理系统04权限管理和动态挂菜单功能) 改写MainFrame的构造方法 新增LoginFrame的验证登录是否成功的代码 新增Logi ...

  8. 傻瓜式使用SpringSecurity完成前后端分离+JWT+登录认证+权限控制

    流程分析 流程说明: 客户端发起一个请求,进入 Security 过滤器链.当到 LogoutFilter 的时候判断是否是登出路径,如果是登出路径则到 logoutHandler ,如果登出成功则到 ...

  9. thinkjs连接mysql_ThinkJS入门+实例(实现认证权限等基本功能)

    这是一篇关于ThinkJS框架的文章,因为网上对于该框架的介绍非常少,所以在这里通俗讲解一下自己对该框架基本的认识并且提供了一个练习基本功能的项目. 因为这是基于Node.js的框架,所以先带新手入门 ...

  10. 前后端分离 springboot shiro+jwt token认证 权限校验

    项目源码 国涛/springboot-shiro-jwthttps://gitee.com/dugt/springboot-shiro-jwt GitHub - dugt-1998/springboo ...

最新文章

  1. android各种color值
  2. iphone clearColor 不起作用问题
  3. 21年美赛F题-DEA模型和逻辑回归模型
  4. 安卓ps模拟器_电脑安装模拟器配置要求
  5. phpcms开发微信小程序api
  6. 谷歌浏览器开启深色模式
  7. linux添加静态ipv6路由,请问如何在CentOS7上配置已经静态路由好的IPv6地址块?
  8. 智能家居竞品分析:米家/HomeKit/美居/涂鸦智能的体验与思考
  9. EDK2-UEFI开发
  10. 2017百度之星初赛a
  11. 03_sourceinsight护眼背景
  12. 2020成考C语言答案,2020年成人高考语文题库(含历年真题练习题模拟题)
  13. Springboot健康饮食小程序的设计的实现毕业设计源码280920
  14. 自我介绍 and 阅读感想
  15. SOCKET的 10035错误
  16. RGB图像中特定颜色的提取
  17. python出租车数据_Python处理JSON格式数据(出租车轨迹数据)
  18. EmguCv模板匹配
  19. 如何用水经注万能地图下载器进行投影转换
  20. 统计物料A与B同时出现的概率,Apriori算法,关联性分析

热门文章

  1. Android开源工具项目集合
  2. Linux基础练习题(二)
  3. UVAlive 6131 dp+斜率优化
  4. window media player出现内部应用程序错误
  5. matlab global(全局变量)
  6. C++设计模式——单例模式
  7. GIS开源库shapeLib的使用方法
  8. c++异常处理机制示例及讲解
  9. sql server 2005单独添加mdf文件
  10. 华为s8600手机驱动_只有手机才能快充?华为MateBook X的灵巧快充解放你的续航焦虑-华为 ——快科技(驱动之家旗下媒体)-...