Flask实战第37天:服务器权限验证

Posted 何波安的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask实战第37天:服务器权限验证相关的知识,希望对你有一定的参考价值。

完成服务器权限验证之前,我们先如下页面先补上

帖子管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    帖子管理-CMS管理系统
{% endblock %}

{% block page_title %}
    帖子管理
{% endblock %}

{% block main_content %}
    这是帖子管理页面
{% endblock %}
cms_posts.html

评论管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    评论管理-CMS管理系统
{% endblock %}

{% block page_title %}
    评论管理
{% endblock %}

{% block main_content %}
    这是评论管理页面
{% endblock %}
cms_comments.html

板块管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    板块管理-CMS管理系统
{% endblock %}

{% block page_title %}
    板块管理
{% endblock %}

{% block main_content %}
    这是板块管理页面
{% endblock %}
cms_boards.html

前台用户管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    前台用户管理-CMS管理系统
{% endblock %}

{% block page_title %}
    前台用户管理
{% endblock %}

{% block main_content %}
    这是前台用户管理页面
{% endblock %}
cms_fusers.html

CMS用户管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    cms用户管理-CMS管理系统
{% endblock %}

{% block page_title %}
    cms用户管理
{% endblock %}

{% block main_content %}
    这是cms用户管理页面
{% endblock %}
cms_cusers.html

CMS组管理

{% extends \'cms/cms_base.html\' %}

{% block title %}
    CMS组管理-CMS管理系统
{% endblock %}

{% block page_title %}
    CMS组管理
{% endblock %}

{% block main_content %}
    这是CMS组管理页面
{% endblock %}
cms_roles.html

 

编辑cms.views.编写对应的视图函数

...
@bp.route(\'/posts/\')
@login_required
def posts():
    return render_template(\'cms/cms_posts.html\')

@bp.route(\'/comments/\')
@login_required
def comments():
    return render_template(\'cms/cms_comments.html\')

@bp.route(\'/boards/\')
@login_required
def boards():
    return render_template(\'cms/cms_boards.html\')

@bp.route(\'/fusers/\')
@login_required
def fusers():
    return render_template(\'cms/cms_fusers.html\')

@bp.route(\'/cusers/\')
@login_required
def cusers():
    return render_template(\'cms/cms_cusers.html\')
cms.views

编辑cms_base.html,修改对应导航的url

...
{% if g.cms_user.has_permission(CMSPersmission.POSTER) %}
  <li class="nav-group post-manage"><a href="{{ url_for(\'cms.posts\') }}">帖子管理</a></li>
{% endif %}

{% if g.cms_user.has_permission(CMSPersmission.COMMENTER) %}
  <li class="comments-manage"><a href="{{ url_for(\'cms.comments\') }}">评论管理</a></li>
{% endif %}

{% if g.cms_user.has_permission(CMSPersmission.BOARDER) %}
  <li class="board-manage"><a href="{{ url_for(\'cms.boards\') }}">板块管理</a></li>
{% endif %}

{% if g.cms_user.has_permission(CMSPersmission.FRONTUSER) %}
  <li class="nav-group user-manage"><a href="{{ url_for(\'cms.fusers\') }}">前台用户管理</a></li>
{% endif %}

{% if g.cms_user.has_permission(CMSPersmission.CMSUSER) %}
  <li class="nav-group cmsuser-manage"><a href="{{ url_for(\'cms.cusers\') }}">CMS用户管理</a></li>
{% endif %}

{% if g.cms_user.has_permission(CMSPersmission.ADMIN) %}
  <li class="cmsrole-manage"><a href="{{ url_for(\'cms.croles\') }}">CMS组管理</a></li>
{% endif %}
cms_base.html

现在点击各导航已经能够正确调到自己的页面了,但是有些导航样式并不是选中的状态

因为之前也提到过,这个选中状态是根据url 来匹配的,所以我们需要去修改cms_base.js

...
$(function () {
    var url = window.location.href;
    if(url.indexOf(\'profile\') >= 0){
        var profileLi = $(\'.profile-li\');
        profileLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
        profileLi.children(\'.subnav\').children().eq(0).addClass(\'active\').siblings().removeClass(\'active\');
    } else if(url.indexOf(\'resetpwd\') >= 0){
        var profileLi = $(\'.profile-li\');
        profileLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
        profileLi.children(\'.subnav\').children().eq(1).addClass(\'active\').siblings().removeClass(\'active\');
    } else if(url.indexOf(\'resetemail\') >= 0){
        var profileLi = $(\'.profile-li\');
        profileLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
        profileLi.children(\'.subnav\').children().eq(2).addClass(\'active\').siblings().removeClass(\'active\');
    } else if(url.indexOf(\'posts\') >= 0){
        var postManageLi = $(\'.post-manage\');
        postManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }else if(url.indexOf(\'boards\') >= 0){
        var boardManageLi = $(\'.board-manage\');
        boardManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }else if(url.indexOf(\'fusers\') >= 0){
        var userManageLi = $(\'.user-manage\');
        userManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }else if(url.indexOf(\'cusers\') >= 0){
        var cmsuserManageLi = $(\'.cmsuser-manage\');
        cmsuserManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }else if(url.indexOf(\'croles\') >= 0){
        var cmsroleManageLi = $(\'.cmsrole-manage\');
        cmsroleManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }else if(url.indexOf(\'comments\') >= 0) {
        var commentsManageLi = $(\'.comments-manage\');
        commentsManageLi.addClass(\'unfold\').siblings().removeClass(\'unfold\');
    }
});
cms_base.js

 

服务端权限验证

之前我们完成了客户端的权限验证,就是不同的账号权限会显示不同的页面(没有权限的页面不会显示)。但是这样还不够。我们使用账号fw@qq.com来看看

因为fw@qq.com只有访问者的权限,所以只能查看到个人中心,但是,它依然能够根据url访问到他本没有权限访问的页面,如帖子管理

所以,只要用户登录后直接输入url ,就轻松绕过了权限这一块,为了解决这个问题,我们还需要在后端做验证

后端验证,我们可以和登录一样,通过装饰器来完成,然后对应的视图函数传入自己对应权限的参数。

就是需要一个传入参数的装饰器,编辑cms.decoratoras.py

...
def permission_required(permission):
    def outter(func):
        @wraps(func)
        def inner(*args, **kwargs):
            #判断该用户是否有权限
            if g.cms_user.has_permission(permission):
                return func(*args, **kwargs)
            else:
                #没有权限则返回到首页
                return redirect(url_for(\'cms.index\'))
        return inner
    return outter    

最后,编辑user.views.py在视图函数中加入上面的装饰器,并传入对应的权限

....
@bp.route(\'/profile/\')
@login_required
@permission_required(CMSPersmission.VISITOR) #这个装饰器要放在login_required下面,因为只有先登录了,才能进下一步验证,
def profile():
    return render_template(\'cms/cms_profile.html\')


@bp.route(\'/posts/\')
@login_required
@permission_required(CMSPersmission.POSTER)
def posts():
    return render_template(\'cms/cms_posts.html\')

@bp.route(\'/comments/\')
@login_required
@permission_required(CMSPersmission.COMMENTER)
def comments():
    return render_template(\'cms/cms_comments.html\')

@bp.route(\'/boards/\')
@login_required
@permission_required(CMSPersmission.BOARDER)
def boards():
    return render_template(\'cms/cms_boards.html\')

@bp.route(\'/fusers/\')
@login_required
@permission_required(CMSPersmission.FRONTUSER)
def fusers():
    return render_template(\'cms/cms_fusers.html\')

@bp.route(\'/cusers/\')
@login_required
@permission_required(CMSPersmission.CMSUSER)
def cusers():
    return render_template(\'cms/cms_cusers.html\')

@bp.route(\'/croles/\')
@login_required
@permission_required(CMSPersmission.ADMIN)
def croles():
    return render_template(\'cms/cms_croles.html\')

 

以上是关于Flask实战第37天:服务器权限验证的主要内容,如果未能解决你的问题,请参考以下文章

Flask实战第41天:发送短信验证码

Flask实战第40天:图片验证码生成技术

Flask实战第53天:cms编辑轮播图功能完成

Flask实战第46天:完成前台登录功能

Flask实战第67天:Flask+Celery实现邮件和短信异步发送

Flask实战第47天:首页导航条首先和代码抽离