flask视频网站(权限控制)

本文介绍了如何在Flask框架下实现基于角色的访问权限控制(RBAC)。内容包括创建权限表单、定义视图、角色与权限的关联、管理员角色分配以及权限装饰器的使用,详细阐述了如何限制不同管理员的URL访问权限,并讨论了超级管理员的权限设定。此外,文章还探讨了如何初始化和管理超级管理员的权限。
摘要由CSDN通过智能技术生成

Auth

  • 基于角色的访问权限控制
    • 有的管理员只能访问日志,而有的能访问会员列表,有的管理电影
    • 这部分还属于admin
  • 从创建表单模型开始,别着急
    class AuthForm(FlaskForm):
        """访问权限控制"""
        name = StringField(
            label='权限名称',
            validators=[
                DataRequired("请输入权限名称!")
            ],
            description="权限",
            render_kw={
                "class": "form-control",
                "placeholder": "请输入权限名称!"
            }
        )
        url = SubmitField(
            label="权限地址",
            validators=[
                DataRequired("请输入权限地址!")
            ],
            description="权限地址",
            render_kw={
                "class": "btn btn-primary",
                "placeholder": "请输入权限地址!"
            }
        )
    
        submit = SubmitField(
            label="添加",
            render_kw={
                "class": "btn btn-primary"
            }
        )
    
  • 定义视图,注意要指定GET/POST方法
    1
    • 这就很明显了,name字段存储操作的名称,url是这个操作在view中定义的访问路径
    • 访问权限控制就是限制能访问的url
  • 删除编辑查看等操作,与之前同理

Role

  • 给角色赋予权限
  • 表单模型,这里使用到多选
    class RoleForm(FlaskForm):
        """管理员角色"""
        name = StringField(
            label='角色名称',
            validators=[
                DataRequired("请输入角色名称!")
            ],
            description="角色",
            render_kw={
                "class": "form-control",
                "placeholder": "请输入角色名称!"
            }
        )
        auth = SelectMultipleField(
            label="权限列表",
            validators=[
                DataRequired("请选择权限")
            ],
            coerce=int,
            # 选择之后,会将id返回
            choices=[(v.id, v.name) for v in auths],
            description="权限列表",
            render_kw={
                "class": "form-control",
            }
        )
    
        submit = SubmitField(
            label="添加",
            render_kw={
                "class": "btn btn-primary"
            }
        )
    
  • 角色只是给管理员的一顶帽子,最终的限定还是通过装饰器关联Auth和Admin
  • 列表、删除和编辑

Admin

  • 给管理员赋予角色,这里使用到关联查询和if判断超管
    class AdminForm(FlaskForm):
        """管理员管理"""
        name = StringField(
            label='管理员名称',
            validators=[
                DataRequired("请输入管理员名称!")
            ],
            description="管理员",
            render_kw={
                "class": "form-control",
                "placeholder": "请输入管理员名称!"
            }
        )
        pwd = PasswordField(
            label="管理员密码",
            validators=[
                DataRequired("请设置管理员密码")
            ],
            description="管理员密码",
            render_kw={
                "class": "form-control",
                "placeholder": "请输入管理员密码"
            }
        )
    
        repwd = PasswordField(
            label="重复管理员密码",
            validators=[
                DataRequired("请重复管理员密码"),
                EqualTo('pwd', message="两次密码不一致!")
            ],
            description="重复管理员密码",
            render_kw={
                "class": "form-control",
                "placeholder": "请重复管理员密码"
            }
        )
    
        # 最好跟数据库的字段名保持一致
        role_id = SelectField(
            label="角色列表",
            validators=[
                DataRequired("请选择角色")
            ],
            # 选择之后,会将id以列表返回
            choices=[(v.id, v.name) for v in roles],
            description="角色列表",
            render_kw={
                "class": "form-control",
            }
        )
    
        is_super = SelectField(
            label="是否为超级管理员",
            validators=[
                DataRequired("0:是  1:不是")
            ],
            description="是否设置为超级管理员",
            coerce=int,
            choices=[v for v in (0,1)],
            render_kw={
                "class": "form-control",
                "id": "input_is_super_id"
            }
        )
    
        submit = SubmitField(
            label="编辑",
            render_kw={
                "class": "btn btn-primary"
            }
        )
    
    # 管理员列表
    @admin.route('/admin/list/<int:page>', methods=["GET"])
    @admin_login
    def admin_list(page=None):
        if page is None:
            page = 1
        # 关联表的数据以 表名.字段 获取
        page_data = Admin.query.join(
            Role
        ).filter(
            Role.id == Admin.role_id
        ).order_by(
            Admin.addtime.desc()
        ).paginate(page=page, per_page=3)
        return render_template('admin/adminlist.html', page_data=page_data)
    
  • 最终超管只通过is_super字段确定,role_id不起作用
    {% if v.is_super==0 %}
    	<td>超级管理员</td>
    {% else %}
    	<td>普通管理员</td>
    {% endif %}
    

权限控制

  • 权限——角色——管理员,最终需要使用装饰器,查询出当前登录管理员所拥有权限,限制访问
    • 超管使用角色,授权各管理员
    • 管理员登录后,会经过装饰器,根据admin表中授权的角色,限制访问路径
  • 超管授权存储在admin表,所以最终在这里查询
    # 权限控制装饰器
    def admin_auth(func):
        @wraps(func)
        def dec_func(*args, **kwargs):
            admin = Admin.query.join(
                Role
            ).filter(
                # 当前登录对象
                Admin.id == session["admin_id"],
                # 被授权的角色
                Role.id == Admin.role_id
            ).first()
            auths = admin.role.auths    # 获取可访问路径
            auths = list(map(lambda v:str(v), auths.split(",")))    # 权限id
            print(auths)
            # 将授权路径搞到列表中
            auth_urls = Auth.query.all()
            urls = [v.url for v in auth_urls for val in auths if int(val)==v.id] # 嵌套for循环,最终if判断
            rule = str(request.url_rule) # 请求的路径
            print(urls)
            print(rule) # 这个多了个/admin,在哪定义?
            # 限制访问:
            if rule[6:] not in urls:# 先使用截取的办法实现功能
                abort(404)
            return func(*args, **kwargs)
        return dec_func
    
    • 根据role表中的授权情况,即可限制管理员访问!
  • 如何初始化定义超管的权限?可以通过直接在数据库中添加所有角色实现
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Roy_Allen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值