Flask 构建微电影视频网站(五)

基于角色的访问控制

权限管理

class AuthForm(FlaskForm):
    name = StringField(
        label='权限',
        validators=[
            DataRequired("请输入权限!"),
        ],
        description='权限',
        render_kw={
            "class": "form-control",
            "placeholder": "请输入权限!"
        }
    )

    url = StringField(
        label='权限地址',
        validators=[
            DataRequired("请输入权限地址!"),
        ],
        description='权限地址',
        render_kw={
            "class": "form-control",
            "placeholder": "请输入权限地址!"
        }
    )
    submit = SubmitField(
        '编辑',
        render_kw={
            "class": "btn btn-primary",
        }
    )
添加权限
@admin.route('/auth/add/', methods=['GET', 'POST'])
@admin_login_req
def auth_add():
    form= AuthForm()
    if form.validate_on_submit():
        data = form.data
        auth = Auth(
            name=data['name'],
            url=data['url']
        )

        db.session.add(auth)
        db.session.commit()

        flash('权限添加成功!', 'info')
    return render_template('admin/auth_add.html',form=form)
权限列表
@admin.route('/auth/list/<int:page>/')
@admin_login_req
def auth_list(page=1):
    if page <= 0:
        page = 1
    page_data = Auth.query.order_by(
        Auth.addtime.desc()
    ).paginate(page=page, per_page=10)
    return render_template('admin/auth_list.html',page_data=page_data)
删除权限
@admin.route('/auth/del/<int:id>/')
@admin_login_req
def auth_del(id=None):
    auth = Auth.query.get_or_404(int(id))
    db.session.delete(auth)
    db.session.commit()
    flash('权限删除成功!', 'info')
    return redirect(url_for('admin.auth_list', page=1))
编辑权限
@admin.route('/auth/edit/<int:id>/', methods=['GET', 'POST'])
@admin_login_req
def auth_edit(id=None):
    form = AuthForm()
    auth = Auth.query.get_or_404(int(id))

    if form.validate_on_submit():
        data = form.data
        auth.name =data['name']
        auth.url=data['url']

        db.session.add(auth)
        db.session.commit()

        flash('权限修改成功!', 'info')
        return redirect(url_for('admin.auth_edit', id=id))
    return render_template('admin/auth_edit.html',form=form, auth=auth)

修改对应的前端文件

角色管理

class RoleForm(FlaskForm):
    name = StringField(
        label='角色名称',
        validators=[
            DataRequired("请输入角色名称!"),
        ],
        description='角色名称',
        render_kw={
            "class": "form-control",
            "placeholder": "请输入角色名称!"
        }
    )

    auths = SelectMultipleField(
        label='权限列表',
        validators=[
            DataRequired("请选择权限!"),
        ],
        coerce=int,
        choices=[(v.id, v.name) for v in auths],
        description='权限列表',
        render_kw={
            "class": "form-control",
        }
    )
    submit = SubmitField(
        '编辑',
        render_kw={
            "class": "btn btn-primary",
        }
    )
添加角色
@admin.route('/role/add/', methods=['GET', 'POST'])
@admin_login_req
def role_add():
    form = RoleForm()
    if form.validate_on_submit():
        data=form.data
        role = Role(
            name=data['name'],
            auths=','.join(map(lambda v:str(v), data['auths']))
        )

        db.session.add(role)
        db.session.commit()
        flash('角色添加成功!', 'info')
    return render_template('admin/role_add.html',form=form)
角色列表
@admin.route('/role/list/<int:page>/')
@admin_login_req
def role_list(page=1):
    if page <= 0:
        page = 1
    page_data = Role.query.order_by(
        Role.addtime.desc()
    ).paginate(page=page, per_page=10)
    return render_template('admin/role_list.html',page_data=page_data)
删除角色
@admin.route('/role/del/<int:id>/')
@admin_login_req
def role_del(id=None):
    role = Role.query.get_or_404(int(id))
    db.session.delete(role)
    db.session.commit()
    flash('角色删除成功!', 'info')
    return redirect(url_for('admin.role_list', page=1))
修改权限
@admin.route('/role/edit/<int:id>/', methods=['GET', 'POST'])
@admin_login_req
def role_edit(id=None):
    form = RoleForm()
    role = Role.query.get_or_404(int(id))

    if request.method == 'GET':
        auths = role.auths
        form.auths.data = list(map(lambda x: int(x), auths.split(',')))

    if form.validate_on_submit():
        data=form.data
        role.name = data['name']
        role.auths = ','.join(map(lambda v:str(v), data['auths']))

        db.session.add(role)
        db.session.commit()
        flash('角色修改成功!', 'info')
    return render_template('admin/role_edit.html',form=form,role=role)

修改对应的前端文件

管理员管理

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": "请输入管理员密码!",
            "required": "required"
        }
    )

    repwd = PasswordField(
        label='管理员重复密码',
        validators=[
            DataRequired("请输入管理员重复密码!"),
            EqualTo('pwd', message='两次密码不一致!'),
        ],
        description="管理员重复密码",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入管理员重复密码!",
            "required": "required"
        }
    )

    role_id=SelectField(
        label='所属角色',
        validators=[
            DataRequired("请选择角色!")
        ],
        coerce=int,
        choices=[(v.id, v.name) for v in roles],
        description="所属角色",
        render_kw={
            "class": "form-control",
        }
    )

    submit = SubmitField(
        '编辑',
        render_kw={
            "class": "btn btn-primary",
        }
    )
添加管理员
@admin.route('/admin/add/', methods=['GET', 'POST'])
@admin_login_req
def admin_add():
    form = AdminForm()

    from werkzeug.security import generate_password_hash

    if form.validate_on_submit():
        data = form.data
        admin = Admin(
            name=data['name'],
            pwd=generate_password_hash(data['pwd']),
            role_id=data['role_id'],
            is_super=1,
        )

        db.session.add(admin)
        db.session.commit()

        flash('管理员添加成功!', 'info')

    return render_template('admin/admin_add.html',form=form)
管理员列表
@admin.route('/admin/list/<int:page>/')
@admin_login_req
def admin_list(page=1):
    if page <= 0:
        page = 1
    page_data = Admin.query.join(
        Role
    ).filter(
        Role.id==Admin.role_id
    ).order_by(
        Admin.addtime.desc()
    ).paginate(page=page, per_page=10)
    return render_template('admin/admin_list.html',page_data=page_data)

修改对应的前端代码

访问权限控制

def admin_auth(func):
    @wraps(func)
    def decorated_function(*args, **kwargs):
        admin = Admin.query.join(
            Role
        ).filter(
            Role.id == Admin.role_id,
            Admin.id==session['admin_id']
        ).first()

        auths = admin.role.auths
        auths = list(map(lambda x: int(x), auths.split(',')))

        auth_list = Auth.query.all()
        urls = [v.url for v in auth_list for val in auths if val == v.id]
        rule = request.url_rule

        print(urls)
        print(rule)

        if str(rule) not in urls:
            abort(404)
        return func(*args, **kwargs)
    return decorated_function

给视图函数添加装饰器,像这样

@admin.route('/tag/list/<int:page>/')
@admin_login_req
@admin_auth
def tag_list(page=1):
    ...
原文地址:https://www.cnblogs.com/gaoyongjian/p/10029148.html