drf-jwt配置文件 jwt签发认证源码分析 自定义用户签发认证 simpleui后台管理美化 权限控制 (acl、rbac)

昨日回顾

# 1 接口文档的编写
	-1 word,md 编写----》存放位置:存放共享文件平台,git上
    -2 第三方的接口文档编写平台
    -3 公司自己开发,使用开源搭建  yapi
    -4 自动生成接口文档
    	-djagno+drf:swagger,coreapi
        -FastAPI:自带自动生成接口文档
              
        
   -接口文档应该有的东西
	-接口描述
    -请求地址
    -请求方式
    -请求编码格式
    -请求参数(get请求参数,post,put请求参数)
    	-参数类型
        -参数是否必填
        -参数解释
    -返回数据
    	-json格式示例
        -重点参数解释
    -错误码:写到全局
     
    
# 2 cookie,session,token发展历史
	-会话保持
    	-cookie:存在于客户端浏览器的键值对
        -session:存才于服务端的键值对(文件,内存,数据库。。。)
        -token:三部分:头,荷载,签名
            	-签发:登录
                -认证:登录后才能访问的接口
                	-认证类
                    -中间件
                    -装饰器
                    -别的位置
            
            
# 3 jwt:json web token :前后端认证的机制,token的web形式认证机制

# 4 base64
	-jwt
    -前后端交互:字符串---》base64编码
    -图片:使用base64编码
 
    
# 5 django+drf如何使用jwt
	-drf-jwt
    
    
# 6 快速签发
	-配置一条路由----》帮咱们写了登录接口
    
# 7 定制返回格式
	-写一个函数,返回什么,前端就看到什么
    -配置文件中配置
# 8 jwt 的认证
	-局部:视图类上 
    	-认证类  ---》JSONWebTokenAuthentication
    	-权限类:drf  IsAuthenticated
    -全局
    
    
    -携带token
    	-请求头中
        	Authorization:jwt sadsfasdfasdf.asdfas'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300)df.asdfasdf
    
 # jwt 配置问题
	-记住的
    	-JWT_RESPONSE_PAYLOAD_HANDLER
        -'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300)
    -了解的
    	'JWT_AUTH_HEADER_PREFIX': 'JWT',
        'JWT_SECRET_KEY': settings.SECRET_KEY,

接口文档

image-20230210084451645

自动生成接口文档

关于框架学习顺序:
Django ---> Flask ---> FastAPI框架(使用多)

  • django+drf:coreapi --基于--> swagger
  • FastAPI:异步框架,自带自动生成接口文档。

FastAPI自动生成的接口文档示例:

image-20230210084324263

接口文档必备的内容

image-20230210084752414

最开始的web只用于浏览文档、浏览新闻

交互式的web兴起 ---> 需要保存用户登录状态 ---> 和用户交互
会话保持 ---> 服务端分的清楚来到服务端的请求是谁
由于服务具有以下特性:无状态无连接
导致服务器,记不住来的请求是谁,所以出现了cookie+session技术。

image-20230210090100368

session占用服务器空间,开销比较大,吃不消 ---> 出现token技术

token原理

token串的三部分,用.分开:

  • 荷载 最重要 但是不要放用户密码 有时候放签发时间
  • 签名 头和载荷 ---> 通过(加密算法+密钥)运算 ---> 签名

签发阶段
认证阶段:登录之后才能访问的接口 ·
--认证类
--中间件
--装饰器
--别的位置

base64

image-20230210090609731

base64长度一定是4的倍数。不足4的倍数的时候,需要使用=补齐。

快速签发

通过jwt自动生成的路由

定制返回格式

进行配置:

image-20230210090856039

drf-jwt默认配置:

image-20230210090938273

可见密钥使用的是django settings密钥。

在django settings配置jwt密钥:

image-20230210091040246

jwt的认证

需要配合drf权限类一起使用。

认证类 ---> jwt ---> JSONWebTokenAuthentication
权限类 ---> drf ---> IsAuthenticated

前端发送请求token需要放在请求头,还需要使用固定的格式:

image-20230210093559617

三大认证:

img

drf-jwt配置文件

需要关注的地方:

前缀:默认是jwt
对应前端请求头 token字符串前面的前缀。

image-20230210093226378

过期时间:默认5分钟token过期

image-20230210093238121

drf-jwt源码执行流程

前期准备

配置login路由:

image-20230210095807864

auth表创建超级用户:

image-20230210095838549

auth表:

image-20230210095850925

auth表密文生成原理

#1 django 的auth  user表,密码是加密的,即便的同样的密码,密文都不一样
	-每次加密,都随机生成一个盐,把盐拼在加密后的串中
# 比如
pbkdf2_sha256$260000$B9ZRmPFpWb3H4kdDDmgYA9$CM3Q/ZfYyXzxwvjZ+HOcdovaJS7681kDsW77hr5fo5o=

明文:lqz12345 
盐:B9ZRmPFpWb3H4kdDDmgYA9

后期来了明文lqz12345

#2 自定义用户表,生成密码用密文
from django.contrib.auth.hashers import make_password

#3  用户表的密码忘了怎么办
	-新增一个用户,把它的密码复制过去
  
# 4 双token认证

auth表的密码如何生成?
同样的密码在auth表存放的密文都不一样。(高级)
再使用同样密码创建一个用户:密文不一样

image-20230210100138071

如何实现? ---> 动态加盐

image-20230210100242047

每次加密都生成一个随机盐。(比如uuid,生成随机字符串)

image-20230210100403484

后端密码校验的时候怎么校验:
根据用户名 取出随机盐 运算出真正的密码?
再和数据库中密文进行比对。

随机盐 + 用户密码明文 --md5加密--> 用户密文

auth表存放的密文 = 固定前缀 + 随机盐 + 用户密文

make_password函数生成密文

make_password源码:

def make_password(password, salt=None, hasher='default'):
    """
    Turn a plain-text password into a hash for database storage

    Same as encode() but generate a new random salt. If password is None then
    return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string,
    which disallows logins. Additional random string reduces chances of gaining
    access to staff or superuser accounts. See ticket #20079 for more info.
    """
    if password is None:
        return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
    if not isinstance(password, (bytes, str)):
        raise TypeError(
            'Password must be a string or bytes, got %s.'
            % type(password).__qualname__
        )
    hasher = get_hasher(hasher)
    salt = salt or hasher.salt()
    return hasher.encode(password, salt)

image-20230210200234525

这里传入给make_password()方法的是明文的密码。通过该方法生成密文的password,保存到user对象中,然后再调用user.save,存到数据库。

通过django的make_password函数生成密文:image-20230210101044686

django 校验密文的函数在哪?
from django.contrib.auth.hashers import check_password

image-20230210101203272

忘记密码?
创建一个用户 生成一个密码 把密码复制到数据库中 进去用完了之后 再把数据库原来的密码复制回来。

jwt签发源码分析

# 登录接口,路由匹配成功,执行obtain_jwt_token---》post请求---》ObtainJSONWebToken的post方法
	path('login/', obtain_jwt_token),
    
    
# ObtainJSONWebToken的post方法 继承APIView
    def post(self, request, *args, **kwargs):
        # 实例化得到序列化类
        serializer = self.get_serializer(data=request.data)
        # 做校验:字段自己,局部钩子,全局钩子
        if serializer.is_valid():
            # user:当前登录用户
            user = serializer.object.get('user') or request.user
            # 签发的token
            token = serializer.object.get('token')
            # 构造返回格式,咱们可以自定制---》讲过了
            response_data = jwt_response_payload_handler(token, user, request)
            response = Response(response_data)
            if api_settings.JWT_AUTH_COOKIE:
                expiration = (datetime.utcnow() +
                              api_settings.JWT_EXPIRATION_DELTA)
                response.set_cookie(api_settings.JWT_AUTH_COOKIE,
                                    token,
                                    expires=expiration,
                                    httponly=True)
            #最终返回了咱们定制的返回格式
            return response

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    
    
    
 # 如何得到user,如何签发的token----》在序列化类的全局钩子中得到的user和签发的token
	-JSONWebTokenSerializer---全局钩子---validate
    	#前端传入,校验过后的数据---》{"username":"lqz","password":"lqz1e2345"}
        def validate(self, attrs):
        credentials = {
            # self.username_field: attrs.get(self.username_field),
            'username':attrs.get('username')
            'password': attrs.get('password')
        }

        if all(credentials.values()):
            # auth 模块,authenticate 可以传入用户名,密码如果用户存在,就返回用户对象,如果不存就是None
            # 正确的用户
            user = authenticate(**credentials)

            if user:
                # 校验用户是否是活跃用户,如果禁用了,不能登录成功
                if not user.is_active:
                    msg = _('User account is disabled.')
                    raise serializers.ValidationError(msg)
				# 荷载----》通过user得到荷载   {id,name,email,exp}
                payload = jwt_payload_handler(user)
				
                return {
                    # jwt_encode_handler通过荷载得到token串
                    'token': jwt_encode_handler(payload),
                    'user': user
                }
            else:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "{username_field}" and "password".')
            msg = msg.format(username_field=self.username_field)
            raise serializers.ValidationError(msg)



### 重点:
	1 通过user得到荷载:payload = jwt_payload_handler(user)
    2 通过荷载签发token:jwt_encode_handler(payload)


## 了解:
	# 翻译函数,只要做了国际化,放的英文,会翻译成该国语言(配置文件配置的)
	from django.utils.translation import ugettext as _
	msg = _('Unable to log in with provided credentials.')


image-20230210101834655

image-20230210101925084

image-20230210101949534

image-20230210102256105

jwt 配置文件默认JWT_AUTH_COOKIE这个为None:

image-20230210102317013

用于前后端混合使用 ---> 设置为True ---> 将token写入cookies

如何得到user?如何签发token?
在序列化类的全局钩子得到user,签发token。

image-20230210102716288

逻辑写在序列化类中的validata。

前端上传的字典:

image-20230210103056606

查看序列化类中的validata法:

attrs ---> 前端上传的字典:{"username":"小红", "password":"123"}

image-20230210103118791

相当于取出这些数据,将数据存储在credentials字典中:

image-20230210103249401

credentials.values()校验前端是否上传值。然后将前端上传的字典,放入auth模块的authenticate方法

authenticate方法:传入用户名和密码,如果用户存在则返回用户对象

image-20230210103317869

校验用户是否被禁用了:

image-20230210103432462

产生荷载部分:
image-20230210103549546

通过荷载得到token串(签发token):
image-20230210103648383

is_valid执行完之后,token就已经产生:
image-20230210103851263
就可以直接获取。

修改django中文环境,注意注册app:

image-20230210103956391

做了国际化,错误提示会变成中文。
image-20230210104155336

国际化的原理:将源码中的英文翻译成中文
image-20230210104244253

其实是使用了__这个函数进行翻译,没错这个函数起了个别名就是叫__
image-20230210104320270

jwt认证源码分析

# JSONWebTokenAuthentication---->父类BaseJSONWebTokenAuthentication----》authenticate方法
    def authenticate(self, request):
        # 前端带在请求头中的token 值
        jwt_value = self.get_jwt_value(request)
        # 如果没有携带token,就不校验了
        if jwt_value is None:
            return None

        try:
            # jwt_value就是token
            # 通过token,得到荷载,中途会出错
            # 出错的原因:
            	-篡改token
                -过期了
                -未知错误
            payload = jwt_decode_handler(jwt_value)
        except jwt.ExpiredSignature:
            msg = _('Signature has expired.')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = _('Error decoding signature.')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.InvalidTokenError:
            raise exceptions.AuthenticationFailed()

        # 如果能顺利解开,没有被异常捕获,说明token是可以信任的
        # payload就可以使用,通过payload得到当前登录用户
        user = self.authenticate_credentials(payload)
		# 返回当前登录用户,token
        return (user, jwt_value)
# jwt_value = self.get_jwt_value(request)
    def get_jwt_value(self, request):
        # 拿到了前端请求头中传入的 jwt dasdfasdfasdfa
        # auth=[jwt,asdfasdfasdf]
        auth = get_authorization_header(request).split()
        # 'jwt'
        auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()

        if not auth:
            # 请求头中如果没带,去cookie中取
            if api_settings.JWT_AUTH_COOKIE:
                return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE)
            return None

        if smart_text(auth[0].lower()) != auth_header_prefix:
            return None

        if len(auth) == 1:
            msg = _('Invalid Authorization header. No credentials provided.')
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = _('Invalid Authorization header. Credentials string '
                    'should not contain spaces.')
            raise exceptions.AuthenticationFailed(msg)

        return auth[1]
    
    
    
    
 # 认证类配置了,如果不传jwt,不会校验,一定配合权限类使用

image-20230210111448540

image-20230210104541874

image-20230210104559939

认证类都需要重写authenticate还记得吗?
是因为三大认证中源码会调用这个authenticate
image-20230210112047239

image-20230210105002816

核心:如何校验token 如何得到token
image-20230210105136956

拿到authuser表:通过用户名拿到当前用户image-20230210105241450

token怎么取出来的:
image-20230210105407548

image-20230210105723259

image-20230210105444177

django 会把所有请求头加个大写的httpimage-20230210105459656

image-20230210105804618

基于drf-jwt自定义用户签发与认证

自定义用户签发

from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import UserInfo
from .authentication import JsonWebTokenAuthentication


class UserView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')
        user = UserInfo.objects.filter(username=username, password=password).first()
        if user:
            # 登录成功,签发token
            # 通过user得到payload
            payload = jwt_payload_handler(user)
            # 通过payload得到token
            token = jwt_encode_handler(payload)
            return Response({'code': 1000, 'msg': '登录成功', 'token': token})
        else:
            return Response({'code': 1001, 'msg': '用户名或密码错误'})

建表:

image-20230210112412552

views: Viewset = 魔法类 + APIView

image-20230210112552356

写逻辑:

image-20230210112915518

使用drf-jwt的函数生成token:

image-20230210113456547

通过user对象得到payload载荷,通过payload得到token字符串。

image-20230210113204988

导入配置:

image-20230210113239697

自定义payload:

image-20230210113339304

自定义token串:

image-20230210113416885

配置路由。

image-20230210113617484

向路由发送请求:

image-20230210113634498

基于auth_user表自己写签发。

自定义认证类

前端放在请求头中,并且名字就叫token。django自动加http.

image-20230210114017902

image-20230210114048309

抛异常:

image-20230210114128504

复制源码写token认证:

image-20230210114223912

修改:

image-20230210114340203

导入:

image-20230210114429929

得到当前用户:

image-20230210114547328

base64decode:
解析payload

image-20230210114629656

完整代码:

image-20230210114657849

只要访问异常登录接口,就会去UserInfo表中查异常用户:
希望惰性查询,用到user对象,再去查。

image-20230210114842654

image-20230210114920054

image-20230210115027909

测试认证类:

image-20230210115221335

image-20230210115235117

image-20230210115253976

image-20230210115315450

修改token过期时间:

image-20230210115410718

元组的产生:

image-20230210115455905

token签发出来了,在过期时间内可以一直使用。

双token认证:

image-20230210115715394

simpleui后台管理美化

# 之前公司里,做项目,要使用权限,要快速搭建后台管理,使用djagno的admin直接搭建,django的admin界面不好

#第三方的美化:
	-xadmin:作者弃坑了,bootstrap+jq 
    -simpleui: vue,界面更好看
    
    
    
# 现在阶段,一般前后端分离比较多:django+vue
	-带权限的前端端分离的快速开发框架
    -django-vue-admin
    -自己写

对django admin后台管理进行了美化。

带权限的前后端分离的快速开发框架
-django-vue-admin
-自己写

使用步骤

# 1 安装
	pip install django-simpleui
    
# 2 在app中注册

# 3 调整左侧导航栏----》
	-menu_display对应menus name
    -如果是项目的app,就menus写app
    -菜单可以多级,一般咱们内部app,都是一级
    -可以增加除咱们app外的其它链接---》如果是外部链接,直接写地址,如果是内部链接,跟之前前后端混合项目一样的写法:咱们的案例---》show 的路由
SIMPLEUI_CONFIG = {
    'system_keep': False,
    'menu_display': ['图书管理', '权限认证', '张红测试'],  # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
    'dynamic': True,  # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [
        {
            'name': '图书管理',
            'app': 'app01',
            'icon': 'fas fa-code',
            'models': [
                {
                    'name': '图书',
                    'icon': 'fa fa-user',
                    'url': 'app01/book/'
                },
                {
                    'name': '出版社',
                    'icon': 'fa fa-user',
                    'url': 'app01/publisssh/'
                },
                {
                    'name': '作者',
                    'icon': 'fa fa-user',
                    'url': 'app01/author/'
                },
                {
                    'name': '作者详情',
                    'icon': 'fa fa-user',
                    'url': 'app01/authordetail/'
                },
            ]
        },
        {
            'app': 'auth',
            'name': '权限认证',
            'icon': 'fas fa-user-shield',
            'models': [
                {
                    'name': '用户',
                    'icon': 'fa fa-user',
                    'url': 'auth/user/'
                },
                {
                    'name': '组',
                    'icon': 'fa fa-user',
                    'url': 'auth/group/'
                },
            ]
        },
        {

            'name': '张红测试',
            'icon': 'fa fa-file',
            'models': [
                {
                    'name': 'Baidu',
                    'icon': 'far fa-surprise',
                    # 第三级菜单 ,
                    'models': [
                        {
                            'name': '爱奇艺',
                            'url': 'https://www.iqiyi.com/dianshiju/'
                            # 第四级就不支持了,element只支持了3级
                        }, {
                            'name': '百度问答',
                            'icon': 'far fa-surprise',
                            'url': 'https://zhidao.baidu.com/'
                        }
                    ]
                },
                {
                    'name': '大屏展示',
                    'url': '/show/',
                    'icon': 'fab fa-github'
                }]
        }
    ]
}
	
    
    
# 4 内部app,图书管理系统某个链接要展示的字段---》在admin.py 中----》自定义按钮
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('nid', 'name', 'price', 'publish_date', 'publish')

    # 增加自定义按钮
    actions = ['custom_button']

    def custom_button(self, request, queryset):
        print(queryset)

    custom_button.confirm = '你是否执意要点击这个按钮?'
    # 显示的文本,与django admin一致
    custom_button.short_description = '测试按钮'
    # icon,参考element-ui icon与https://fontawesome.com
    # custom_button.icon = 'fas fa-audio-description'
    # # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    custom_button.type = 'danger'
    # # 给按钮追加自定义的颜色
    # custom_button.style = 'color:black;'
    
    
    
# 5 app名字显示中文,字段名字显示中文
	-新增,查看修改展示中文,在表模型的字段上加:verbose_name='图书名字',help_text='这里填图书名'
	-app名字中文:apps.py---》verbose_name = '图书管理系统'

    
# 6 其它配置项
	SIMPLEUI_LOGIN_PARTICLES = False  #登录页面动态效果
    SIMPLEUI_LOGO = 'https://avatars2.githubusercontent.com/u/13655483?s=60&v=4'#图标替换
    SIMPLEUI_HOME_INFO = False  #首页右侧github提示
    SIMPLEUI_HOME_QUICK = False #快捷操作
    SIMPLEUI_HOME_ACTION = False # 动作

image-20230210120857129

注册:

image-20230210120937670

查看页面:

image-20230210120953949

快速写一个图书管理系统:建表
admin.py:
image-20230210121323688

修改app的名字:
image-20230210121409606

image-20230210121419571

image-20230210121600297

image-20230210121850146

image-20230210121948403

image-20230210122020631

image-20230210122039485

添加按钮:
image-20230210122143385

image-20230210122150927

点按钮就会执行函数:
image-20230210122239977

完整:
image-20230210122309397

image-20230210122351653

添加弹窗也可以做。

添加功能:

image-20230210122503408

修改配置文件:
image-20230210122539003

修改的示例:
image-20230210122618367

menus:
image-20230210122714231

二级菜单和三级菜单:

image-20230210122810929

image-20230210122917701

image-20230210122948971

点击可以访问url.

复制models添加二级菜单:
image-20230210123112509

image-20230210123141361

输入错误的url:

image-20230210150259328

我们写的地址,必须是自动生成的路由之一。

这样不行:
image-20230210150343679

跟表没有必然联系的页面:
写一个我们项目中存在的路径

image-20230210150647370

添加弹出框:image-20230210150712474

image-20230210150758727

image-20230210150815732

image-20230210150820520

还可以layer文件上传。

配置项:
关闭粒子特效。
修改logo。
image-20230210151059690

image-20230210151049386

image-20230210151202454

隐藏快捷动作:image-20230210151231105

这个一定要置为False:image-20230210151320019

image-20230210151526287

image-20230210151702117

app名字显示中文,字段名字显示中文:
在表里写ver_bosename
image-20230210151903846

image-20230210151915646

image-20230210151950579

大屏展示

# 监控大屏展示
	-https://search.gitee.com/?skin=rec&type=repository&q=%E5%B1%95%E7%A4%BA%E5%A4%A7%E5%B1%8F
        
    -就是前后端混合项目,js,css,图片对应好,就可以了

image-20230210152322406

image-20230210152440533

image-20230210152515116

将Index复制到templates,然后写个路由:
image-20230210152828847

ctrl+R全局替换。

image-20230210152951440

image-20230210153042026

image-20230210153227891

image-20230210153432276

每个用户显示的菜单不一样:
image-20230210153507776

所以每次修改代码需要重新登录。

权限控制 (acl、rbac)

# 公司内部项目
	-rbac:是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便
    
    -用户表:用户和角色多对多关系,
    -角色表
    	-一个角色可能有多个权限----》
        	-开发角色:拉取代码,上传代码
        	-财务角色:开工资,招人,开除人
            -
    -权限表:角色和权限是多多多
    	-拉取代码
        -上传代码
        -部署项目
        -开工资
        -招人
        -开除人
        -
    -通过5张表完成rbac控制:用户表,角色表,权限表, 用户角色中间表, 角色权限中间表
    -如果某个人,属于财务角色,单只想要拉取代码权限,不要上传代码权限
    -通过6张表:django的admin----》后台管理就是使用这套权限认证
    	用户表,
        角色表,
        权限表, 
        用户角色中间表, 
        角色权限中间表
        用户和权限中间表
# 互联网项目
	-acl:Access Control List 访问控制列表,权限放在列表中
    -权限:权限表----》 发视频,评论,开直播
    -用户表:用户和权限是一对多
    
    张三:[发视频,]
    李四:[发视频,评论,开直播]
    

# 演示了 django-admin 的权限控制
	-授予lqz 某个组
    -单独授予权限
    
# django -auth--6张表
	auth_user   用户表
	auth_group  角色表,组表
    auth_permission  权限表
    -----------
    auth_user_groups   用户和角色中间表
    auth_group_permissions  角色和权限中间表
	-------------
    auth_user_user_permissions  用户和权限中间表
    
    
# java:若依
# go :gin-vue-admin
# python :django-vue-admin

用户表 和 权限表 一对多关系。
互联网对外的用户:
acl访问控制列表 权限放在列表中
Access Control List

rbac基于角色的访问

开发 总监 总裁办 都是我
用户跟角色是多对多。

角色和权限也是多对多

财务可以发工资 总裁也可以发公司
一个权限多个角色。

不是同时把所有权限都授予某个人。是把权限授予角色,角色再授予用户。

自定义rbac

image-20230210154641824

把开发权限授予财务角色。但是直接授予角色的全部权限,那么这个权限太大了,所有需要自定义权限控制。
image-20230210154956927

给一个组,这个组里面的用户只有查看图书的权限。

新建组:

image-20230210155402827

给组授予权限。

image-20230210155549017

给用户分配组:需要使用root账号
image-20230210155703005

重新登录:
image-20230210155911096

只能看,增删按钮没了。

基于前后端分离的基于rbac的访问控制。
期中架构如果能写个django-admin

公司的权限控制框架。
image-20230210160509337

image-20230210160250457

单独对组中某个用户授予权限,如何设置:

django admin是基于auth表写的:
image-20230210161020949

权限表:
image-20230210161042978

image-20230210161312291

饿了么-vue-admin 开源框架

D2Admin

image-20230210161545951

fastapi vue admin

python casbin0......

image-20230210161827775

开始使用 | Casbin

练习

1 整理 jwt 签发,认证流程     3
2 自定义用户表,签发,认证    4 
3 自定义用户表,使用make_password保存密码 5 密码存在后端不是明文 使用类似django的加密技术

4 simpleui  写个图书管理系统 6
5 演示一下admin  的rbac 7
----------------------
6 研究 python casbin  支持acl rbac,abac。。。。权限控制  1  ---> 还可以耗时间研究
7 双token认证 2
posted @ 2023-02-11 18:12  passion2021  阅读(130)  评论(0编辑  收藏  举报