首页 > 编程语言 >基于自定义表编写认证类、django-jwt源码分析、权限介绍

基于自定义表编写认证类、django-jwt源码分析、权限介绍

时间:2023-09-12 19:14:07浏览次数:46  
标签:自定义 jwt token 源码 user import 权限 payload

一、基于自定义表编写认证类

认证类:

auth.py:

# 写一个类继承BaseAuthentication,重写authenticate方法
from rest_framework.authentication import BaseAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.settings import api_settings
import jwt
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload_handler = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
from .models import User

class JwtAuthentication(BaseAuthentication):
    # 重写authenticate方法
    def authenticate(self, request):
        # 获取前端传入的token进行验证,从请求头中获取token
        token = request.META.get('HTTP_TOKEN')
        # django——jwt 提供了校验token的方法,从这个JSONWebTokenAuthentication这个中找
        try:
            # jwt提供的方法,进行token的校验
            payload = jwt_decode_handler(token)  # 传入token进行校验,校验通过返回payload,校验失败抛异常
            # 通过payload 得到当前用户
            # 认证类,配好后,只要有认证的,都会走这里---》每次走这里都会查询一次数据库
            # 做个优化?
            # 1 自己根据payload数据,创建一个用户,有的参数没传,会使用默认值,跟我真实用户还是有区别的
            # user=User(id=payload.get('user_id'),username=payload.get('username'))
            # 2 直接返回用户id,后续 的request.user 都是用户id,如果真正要用的时候,再查
            user = User.objects.get(pk=payload.get('user_id'))
        except jwt.ExpiredSignature:
            # msg = _('Signature has expired.') # _是个函数的别名,这个函数是翻译函数,只要做了国际化,它就是中文
            msg = '签名过期'
            raise AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = 'token错误'
            raise AuthenticationFailed(msg)
        except jwt.InvalidTokenError:
            msg = 'token不合法'
            raise AuthenticationFailed(msg)
        except Exception:
            raise AuthenticationFailed('未知错误,请联系系统管理员')
        return (user, token)  # 后续的request.user 都是用户id,

 登录接口:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings  # drf的配置文件# from rest_framework_jwt.utils import jwt_payload_handler
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
# rest_framework_jwt.utils.jwt_encode_handler
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from .models import User

# 自定义签发表签发
class UserView(APIView):
    def post(self, request):
        # 拿到前端提交的用户名、密码去表里查询
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()
        if user:
            # 查询到了,说明用户名、密码正确,进行token签发
            # 通过user生成payload,jwt中有提供一个方法:
            payload = jwt_payload_handler(user)
            # jwt提供的方法:通过payload生成token
            token = jwt_encode_handler(payload)
            return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username})
        else:
            return Response({'code': 101, 'msg': '用户名或者密码错误'})

路由:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/',UserView.as_view()), # 自定义表签发路由
    path('test/', TestView.as_view()), #自定义表认证的测试接口路由
]

视图类:

# 测试接口
from rest_framwork.views import APIView
from .auth import JwtAuthentication
# 测试接口
class TestView(APIView):
    # 登录之后才能访问
    authentication_classes = [JwtAuthentication]
    def get(self,request):
        print(request.user) # User object (1)
        return Response({'code':100,'msg':'测试成功'})

postman测试结果:

 

二、 django-jwt源码分析

签发源码分析:

1. 入口:obtain_jwt_token 

  -from rest_framework_jwt.views import obtain_jwt_token

2. obtain_jwt_token的本质:ObtainJSONWebToken.as_view()

3. 看ObtainJSONWebToken视图类

  - 前端POST请求,提交了用户名和密码,就能签发token

  - 去 ObtainJSONWebToken中找post方法

4. 去父类JSONWebTokenAPIView中找post方法,

 5. 校验用户名密码和生成token,写在了序列化类:JSONWebTokenSerializer的全局钩子validate中:

 

总结:

  - 前端携带用户名、密码到后端,执行后端的post方法,后端生成一个序列化类的对象

  - serializer.is_valid(),进行数据校验,走了全局钩子validate

  - 全局钩子中通过用户名和密码获取用户,如果获取不到,就抛异常

  - 获取到之后签发token

  - 签发完后返回,在视图类中,取出来,返回给前端

认证源码分析:

1. 从哪里看----》认证类:JSONWebTokenAuthentication

2. JSONWebTokenAuthentication:

 从父类BaseJSONWebTokenAuthentication类中找到了authenticate方法:

 三、权限介绍

所有项目都会有权限控制

1. ACL(访问控制列表)

  ACL是访问控制列表(Access Control List),针对互联网用户,多半是这个

  在ACL中,将用户与权限对接(多对多):一个用户可以有多个权限,一个权限可以被多个用户拥有

   比如:张三:[发视频,点赞,评论]

      李四:[看视频]

2. RBAC(基于角色的访问控制)

  RBAC 是基于角色的访问控制(Role-Based Access Control ):公司内部项目

  在 RBAC 中,将权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。django的 admin+auth 就是使用了这套认证机制。

python写公司内部项目比较多,使用rbac控制居多

如何设计:

  -用户表---》一堆用户:张三,李四
  -角色表(group组)---》用户的角色:后勤部,开发部,总裁办。。。
  -权限表-----》放了一堆权限:发电脑,提交代码,删除代码,发工资
  -用户和角色多对多:一个用户属于多个角色,一个角色属于多个用户
  -角色 和权限多对多:一个角色有多个权限,一个权限属于多个角色
  --------rabc----通过5张表可以实现
  -django为了更细粒度划分---》多了一张表,用户和权限多对多

演示django的RABC权限控制:

 

3. ABAC(基于属性的访问控制)

  ABAC是基于属性的访问控制(Atrribute-Based Access Control),又称为PBAC(Policy-Based Access Control,基于策略的访问控制),CBAC(Claims-Based Access Control,基于声明的访问控制)。

  传统的ACL、RBAC的架构是{subject,action,object},而ABAC的架构是{subject,action,object,contextual}且为他们添加了parameter(参数)。

  subject属性:比如用户的年龄、部门、角色、威望、积分等主题属性

  action属性:比如查看、读取、编辑、删除等行为属性

  object属性:比如银行账户、文章、评论等对象或资源属性

  contextual属性:比如时段、IP位置、天气等环境属性

四、simpleui的使用

公司内部,做公司内的项目需要使用这套权限控制

方案一:使用django-admin写

有的公司,不怎么写前端,直接使用django的admin,快速写出一套具有权限管理的系统

django-admin的界面不好看:第三方美化---》simpleui

方案二:自己写,前端使用vue,后端使用django,做公司内部的项目

  - 第三方开源的权限控制 项目

    - python界:django-vue-admin 

    - java界:若依

    - go界:gin-vue-admin

 

标签:自定义,jwt,token,源码,user,import,权限,payload
From: https://www.cnblogs.com/Lucky-Hua/p/17697198.html

相关文章

  • 04 自定义注解
    packageannotate;importjava.lang.annotation.*;importstaticjava.lang.annotation.ElementType.*;importstaticjava.lang.annotation.RetentionPolicy.RUNTIME;@myAnnotate(age=18)publicclassTest03{@myAnnotate1(20)//当参数只有一个时,value可以不......
  • Spring源码分析(六)容器的扩展点(BeanFactoryPostProcessor)
    之前的文章我写了BeanDefinition的基本概念和合并,其中很对次提到了容器的扩展点,这篇文章就写这方面的知识。这部分的内容主要涉及到官网的1.8小节。按照官网介绍来说,容器的扩展点可以分为三类,BeanPostProcessor,BeanFactoryPostProcessor以及FactoryBean。本文主要讲BeanFactoryPost......
  • 使用EasyExcel实现无模板、全自定义Excel导出
    1需求背景最近公司需要做一个动态字段的Excel导出,大致的样式如下:实体类如下://部门实体类publicclassDepartment{privateStringcompanyName;privateStringname;privateStringfullName;privateStringleaderName;privateStringbusiness;......
  • 【玩转鲲鹏 DevKit系列】如何快速迁移无源码应用?
    本文分享自华为云社区《【玩转鲲鹏DevKit系列】如何快速迁移无源码应用?》,作者:华为云社区精选。为了帮助广大用户和开发者快速将无源码应用从x86迁移到鲲鹏,鲲鹏DevKit提供了动态二进制翻译工具ExaGear,它能在运行时将x86二进制指令翻译成鲲鹏二进制指令,使得大部分x86应用无需......
  • 开源即时通讯(IM)项目OpenIM源码部署流程
    由于OpenIM依赖的组件较多,开发者需求不一,导致OpenIM部署一直被人诟病,经过几次迭代优化,包括依赖的组件compose的一键部署,环境变量设置一次,全局生效,以及脚本重构,目前OpenIM部署比较丝滑,特写文章分享给大家。OpenIM是什么OpenIM不是一个独立的聊天产品,它不像telegram、S......
  • kubernetes部署mongoDB 单机版 自定义配置文件、密码、日志路径等
    来源:https://aijishu.com/a/1060000000097166官方镜像地址: https://hub.docker.com/_/mong...docker版的mongo移除了默认的/etc/mongo.conf,修改了db数据存储路径为/data/db.创建configmap配置,注意不能加fork=true,否则Pod会变成Completed。apiVersion:v1kind:ConfigMap......
  • [SpringSecurity5.2.2源码分析七]:WebAsyncManagerIntegrationFilter
    1、作用• 是为了接口返回异步对象,然后执行异步任务也能通过SecurityContextHolder获取SecurityContext• 比如说返回值是WebAsyncTask的时候2、WebAsyncManagerIntegrationFilter• 源码很短就是在WebAsyncManager中注册了SecurityContextCallableProcessingInterceptorpublic......
  • 基于微信小程序的高校宿舍报修系统-计算机毕业设计源码+LW文档
    一、研究背景及意义研究背景:学生宿舍是学生学习,生活,休息,交往的重要场所,做好宿舍管理工作,构建安全校园,是校园管理的一项重要任务。目前我们传统的宿舍管理存在一些弊端,传统考勤制度,信息传达不及时,依赖人工管理,人员管理过程冗杂,无精准数据分析,宿舍安全隐患,家校无法互通等问题。在我......
  • 综合性养老服务平台的设计与实现-计算机毕业设计源码+LW文档
    一、研究的背景意义当前,随着我国老龄化程度加急,各地纷纷构建高品质的养老院来适应城市的发展,养老院品质的上升并不等于养老院服务质量的上升,这就对养老院管理提出更高的要求。在传统的养老院管理中,许多工作都是依靠人力去解决。比如老人管理、水电费管理需要通过工人进行记录,往往积......
  • 微信小程序校园服务平台的设计与实现-计算机毕业设计源码+LW文档
    研究现状:1.国外研究现状早在2015年,设计师弗朗西斯·贝里曼和GoogleChrome的工程师亚历克斯·罗素提出“PWA(渐进式网络应用程序)”概念,其核心目标就是提升WebApp的性能,改善WebApp的用户体验。媲美Native的流畅体验,将网络之长与应用之长相结合。根据Google开发者支持页面,PWA相关......